# Loop within loop Question

38

I'm trying to draw color coded H Lines for each pipette.  The inner loop has no problems - 0 through 9.  My problem is how to create another loop once 9 becomes 10.  I need to restart the loop to draw lines for 0 to 9, between 10 and 20, etc.  Each time i reset   j   I end up with an endless loop.   I've tried a number of different calculations, to try and get around this problem, but either ended up in endless loop or division by 0.   If the language was Basic, it would only take me a couple minutes to write this.  I've done it many times.  Loops within loops within loops.  Some counting forward and some backwards, at the same time.  This language is more about logic.  Your logic has to be perfect.  No holes where the program can draw a different conclusion, or go into limbo.  Everything has to be in a specific order so that there is no other alternative.

Could someone look at this code, and perhaps, point me in the right direction?

Thanks!
```//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//|                                                                  |
//|                                                                  |
//|                                                                  |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
#property indicator_chart_window

//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| Custom indicator initialization function                         |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
int init()
{

//~~~~
return(0);
}
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| Custom indicator deinitialization function                       |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
int deinit()
{
//----
int ObjectCount = ObjectsTotal();
for (int s=ObjectCount-1; s>=0; s--)
{
if(StringFind(ObjectName(s),"InnerA") != -1)
{
ObjectDelete(ObjectName(s));
} }

for (int n=ObjectCount-1; n>=0; n--)
{
if(StringFind(ObjectName(n),"Inner") != -1)
{
ObjectDelete(ObjectName(n));
}

}
//----
return(0);
}
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| Custom indicator iteration function                              |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
int start()
{
int j;
double T, L;

double DayH = iHigh(NULL, PERIOD_D1,0);
double X = 1.11100;

//  int Y = (( DayH - X )*100000);

if ( T != DayH )

{

//   for ( int i=0; i<10; )
//     {

// if ( j == 9 )
//    { X = ( T + 0.00010; j = 0; )}  //

//  Alert("2X  =  ",DoubleToStr(NormalizeDouble(X,5),5),"    T  =  ",DoubleToStr(NormalizeDouble(T,5),5),"   j  =  ",j,"   L  =  ",DoubleToStr(NormalizeDouble(L,5),5));

for( j=0; j<10; )
// while( j < 10)j++
{

L = ( j * 0.00001 );
T = ( X + L );

//    if ( j > 9 )
//  { j = ( L - i ); }

Alert("X  =  ",DoubleToStr(NormalizeDouble(X,5),5),"    T  =  ",DoubleToStr(NormalizeDouble(T,5),5),"   j  =  ",j,"   L  =  ",DoubleToStr(NormalizeDouble(L,5),5));

if ( j == 9 )
{
ObjectDelete("InnerAA");
ObjectCreate("InnerAA", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAA", OBJPROP_COLOR, Crimson);
ObjectSet("InnerAA", OBJPROP_WIDTH, 1);
ObjectSet("InnerAA", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 8 )
{
ObjectDelete("InnerAB");
ObjectCreate("InnerAB", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAB", OBJPROP_COLOR, Crimson);
ObjectSet("InnerAB", OBJPROP_WIDTH, 1);
ObjectSet("InnerAB", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 7 )
{
ObjectDelete("InnerAC");
ObjectCreate("InnerAC", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAC", OBJPROP_COLOR, Crimson);
ObjectSet("InnerAC", OBJPROP_WIDTH, 1);
ObjectSet("InnerAC", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 6 )
{
}

if ( j == 5 )
{
ObjectDelete("InnerAE");
ObjectCreate("InnerAE", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAE", OBJPROP_COLOR, Crimson);
ObjectSet("InnerAE", OBJPROP_WIDTH, 1);
ObjectSet("InnerAE", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 4 )
{
ObjectDelete("InnerA");
ObjectCreate("InnerA", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerA", OBJPROP_COLOR, Lime);
ObjectSet("InnerA", OBJPROP_WIDTH, 1);
ObjectSet("InnerA", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 3 )
{
ObjectDelete("InnerB");
ObjectCreate("InnerB", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerB", OBJPROP_COLOR, Lime);
ObjectSet("InnerB", OBJPROP_WIDTH, 1);
ObjectSet("InnerB", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 2 )
{
ObjectDelete("InnerC");
ObjectCreate("InnerC", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerC", OBJPROP_COLOR, Lime);
ObjectSet("InnerC", OBJPROP_WIDTH, 1);
ObjectSet("InnerC", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 1 )
{
ObjectDelete("InnerD");
ObjectCreate("InnerD", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerD", OBJPROP_COLOR, Lime);
ObjectSet("InnerD", OBJPROP_WIDTH, 1);
ObjectSet("InnerD", OBJPROP_STYLE, STYLE_DOT);
}

if ( j == 0 )
{
ObjectDelete("InnerE");
ObjectCreate("InnerE", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerE", OBJPROP_COLOR, Lime);
ObjectSet("InnerE", OBJPROP_WIDTH, 1);
ObjectSet("InnerE", OBJPROP_STYLE, STYLE_DOT);
}

//  if ( j == 10)
//  { X = X + .00010; j = 0;}
//  i = j;

j++;

}

// i++;

//  }

}
//~~~~
return(0);
}
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+```
747

```int j = 0;
while(X < 1.23450)
{
L = ( j * 0.00001 );
T = ( X + L );
if(j==0) {
ObjectDelete("InnerE");
ObjectCreate("InnerE", OBJ_HLINE, 0, 0, T);
ObjectSet("InnerE", OBJPROP_COLOR, Lime);
ObjectSet("InnerE", OBJPROP_WIDTH, 1);
ObjectSet("InnerE", OBJPROP_STYLE, STYLE_DOT);
}
...
j++;
if (j == 10) { X = X + .00010; j = 0; }
}```
Maybe this way. You didn't mention when to stop drawing so I assume its some upper bound of X.
38

Thanks!  The inner loop is for ten lines, beginning with pipette 0 and ending with pipette 9.  The loop needs to repeat every 10 lines.  From 0 to 10, 10 to 20,etc.   Each line is assigned it's own color.
747

If you need iterations like this 0..10 10..20 etc, its better to use two nested loops. I guess your problem was how to break (escape) from the inner loop once a stop condition is met. In Basic it's a simple GOTO but here you need to test the condition twice. First check in the inner loop will lead to a break statement. The second check is embedded in the outer loop header. The code will draw lines starting at T until a certain upper bound is hit, I called it Tmax.

```for(int i=0; T<=Tmax; i++)
{
for(int j=0; j<=10; j++)
{
int offset=i*10+j; // 0..10,10..20,20..etc
L = ( offset * 0.00001 );
T = ( X + L );

// check when to stop drawing
if(T > Tmax) break;

if ( j == 0 )
{
// draw the line
}
...
if ( j == 9 )
{
// draw the line
}
}
}```
38

I'm 95% of the way there.  Everything is calculating in the order that it should.  The alerts show that the values, of the next group of lines to be drawn, are there and correct, but the inner loop where the lines are drawn, is not restarting.  Even when the loop is reset to it's starting value.  Break and Continue operators only seem to apply while the loop hasn't completed.  I'm not sure if a Switch operator would have any different outcome.  Could you take a look at the code and see if you can see something that I'm missing.  Only the first set of lines are being drawn.
```//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//|                                                                  |
//|                                                                  |
//|                                                                  |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
#property indicator_chart_window

//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| Custom indicator initialization function                         |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
int init()
{

//~~~~
return(0);
}
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| Custom indicator deinitialization function                       |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
int deinit()
{
//----
int ObjectCount = ObjectsTotal();
for (int s=ObjectCount-1; s>=0; s--)
{
if(StringFind(ObjectName(s),"InnerA") != -1)
{
ObjectDelete(ObjectName(s));
} }

for (int n=ObjectCount-1; n>=0; n--)
{
if(StringFind(ObjectName(n),"Inner") != -1)
{
ObjectDelete(ObjectName(n));
}

}
//----
return(0);
}
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
//| Custom indicator iteration function                              |
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
int start()
{
int j = 0, p = 0, D = 10, N;
double T, L = 0.00001, X, Z;

X = 1.13100;// X = iLow(NULL, PERIOD_D1,0);

while ( j < 10 )   //  Outer Loop   Tens  0 to 9 times 10

{

Alert("Here I am 3! =  ","   T =  ",DoubleToStr(NormalizeDouble(T,5),5),"   X =  ",DoubleToStr(NormalizeDouble(X,5),5),"    p =  ",p,"   j =  ",j);

//  Alert("1p =  ",p,"   D =  ",D,"   j =  ",j);

N=( D * j );   //

if( p > 9 ){ X = ( T + L ); p = 0; Alert(" RESET P TO 0"); }   //  Last Value of T, 0 to 9 loop, carried outside inner loop to outer loop for next set of lines. Next increment added. Inner loop reset.

//  Inner loop not restarting here!!!

for ( p = 0; p < 10; )   //  Inner Loop Ones  0 to 9

{

Z = ( p * L );  //  Multiplier

T = ( X + Z );   //  Multiplier added to Minimum Price

// Alert("Here I am 1! =  ","   T =  ",DoubleToStr(NormalizeDouble(T,5),5),"   X =  ",DoubleToStr(NormalizeDouble(X,5),5),"    p =  ",p,"   j =  ",j);

if ( p == 9 )
{
//  ObjectDelete("InnerAA"+Time[p]);
ObjectCreate("InnerAA"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAA"+Time[p], OBJPROP_COLOR, Crimson);
ObjectSet("InnerAA"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerAA"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 8 )
{
//  ObjectDelete("InnerAB"+Time[p]);
ObjectCreate("InnerAB"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAB"+Time[p], OBJPROP_COLOR, Crimson);
ObjectSet("InnerAB"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerAB"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 7 )
{
//    ObjectDelete("InnerAC"+Time[p]);
ObjectCreate("InnerAC"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAC"+Time[p], OBJPROP_COLOR, Crimson);
ObjectSet("InnerAC"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerAC"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 6 )
{
}

if ( p == 5 )
{
//   ObjectDelete("InnerAE"+Time[p]);
ObjectCreate("InnerAE"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerAE"+Time[p], OBJPROP_COLOR, Crimson);
ObjectSet("InnerAE"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerAE"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 4 )
{
// ObjectDelete("InnerA"+Time[p]);
ObjectCreate("InnerA"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerA"+Time[p], OBJPROP_COLOR, Lime);
ObjectSet("InnerA"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerA"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 3 )
{
//     ObjectDelete("InnerB"+Time[p]);
ObjectCreate("InnerB"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerB"+Time[p], OBJPROP_COLOR, Lime);
ObjectSet("InnerB"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerB"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 2 )
{
//    ObjectDelete("InnerC"+Time[p]);
ObjectCreate("InnerC"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerC"+Time[p], OBJPROP_COLOR, Lime);
ObjectSet("InnerC"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerC"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 1 )
{
//  ObjectDelete("InnerD"+Time[p]);
ObjectCreate("InnerD"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerD"+Time[p], OBJPROP_COLOR, Lime);
ObjectSet("InnerD"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerD"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

if ( p == 0 )
{
//   ObjectDelete("InnerE"+Time[p]);
ObjectCreate("InnerE"+Time[p], OBJ_HLINE, 0, 0, T);
ObjectSet("InnerE"+Time[p], OBJPROP_COLOR, Lime);
ObjectSet("InnerE"+Time[p], OBJPROP_WIDTH, 1);
ObjectSet("InnerE"+Time[p], OBJPROP_STYLE, STYLE_DOT);
}

{ Alert("p =  ",p,"   N =  ",N,"   D =  ",D,"   j =  ",j,"   T =  ",DoubleToStr(NormalizeDouble(T,5),5),"   X =  ",DoubleToStr(NormalizeDouble(X,5),5),"   L =  ",DoubleToStr(NormalizeDouble(L,5),5)); }

p++;

//   Alert("Here I am 2! =  ","   T =  ",DoubleToStr(NormalizeDouble(T,5),5),"   X =  ",DoubleToStr(NormalizeDouble(X,5),5),"    p =  ",p,"   j =  ",j);

}

j++;

}

//~~~~
return(0);
}
//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+```
595

Yellowbeard1881:
I'm 95% of the way there.  Everything is calculating in the order that it should.  The alerts show that the values, of the next group of lines to be drawn, are there and correct, but the inner loop where the lines are drawn, is not restarting.  Even when the loop is reset to it's starting value.  Break and Continue operators only seem to apply while the loop hasn't completed.  I'm not sure if a Switch operator would have any different outcome.  Could you take a look at the code and see if you can see something that I'm missing.  Only the first set of lines are being drawn.

The inner loop is run every time, just that your lines' names are the same, so each new run overwrite the lines drawn by the previous run.

Edit: correction - not "overwrite". Because you use ObjectCreate(), and objects of the same name already exist after the first run, so subsequent runs appear to be non-existent. So (1) if you want additional lines drawn with each run, consider changing the names, or (2) if you want each new run to move the lines, consider using ObjectSet() to change their prices after the first run.
747

Of course a Switch statement would look better in your code but an If - Else construct will do it, too. I recommend to use the standard synopsis for indicator functions, that is OnInit, OnDeinit and OnCalculate. The latter comes with an interesting set of parameters that you could use. And try the Code Styler (Tools-Styler or Ctrl+,) to auto-indent your code, it'll improve readability a lot.
38

Thanks, everyone!  Had to give each line it's own number.  Placed  ph=ph+1;  within inner loop.  Gave each line it's own number by:  ObjectCreate("InnerA"+ph, OBJ_HLINE, 0, 0, T);   Everything works now.

Thanks, again!