PowerLanguage loops can cycle through recent price data or the elements of an array. But what if we want to process historical price bars from multiple data series or loop over a multidimensional array? For that, nested loops are needed.

In this article:

Nested loops in PowerLanguage

A nested loop is a loop that is contained inside the body of another loop (Liberty & Cadenhead, 2011; Stellman & Greene, 2010). When you have two loops, one inside the other, the nested loop is called the inner loop and the outside loop the outer loop (Sempf, Sphar, & Davis, 2010).

The basic pattern of a nested for-to loop is:


for outerLoopCounter = beginValue to endValue begin

    for innerLoopCounter = beginValue to endValue begin

        // Code to repeat for each loop cycle
        // of the inner and outer loop

    end;

    // Code to execute for each outer loop cycle

end;

Because the inner loop is executed for each loop cycle of the outer loop (Liberty & Cadenhead, 2011), the code inside the inner loop will be repeated innerLoopCounter times for each outerLoopCounter.

So when the outer loop runs 3 times and the inner loop 5 times, the code is executed like this: first 5 times the inner loop, then again 5 times the inner loop for the second outer loop cycle, and on the last outer loop cycle again 5 times the inner loop.

A basic nested loop in PowerLanguage

An example of nested loops is:


Variables:
    dataNum(0),
    barsBack(0);

for dataNum = 1 to 3 begin 

    for barsBack = 5 downto 1 begin 

        Print("Data number: ", NumToStr(dataNum, 0), 
            Spaces(5), 
            "BarsBack: ", NumToStr(barsBack, 0));

    end;

end;

//> Data number: 1     BarsBack: 5
//> Data number: 1     BarsBack: 4
//> Data number: 1     BarsBack: 3
//> Data number: 1     BarsBack: 2
//> Data number: 1     BarsBack: 1
//> Data number: 2     BarsBack: 5
//> Data number: 2     BarsBack: 4
//> Data number: 2     BarsBack: 3
//> Data number: 2     BarsBack: 2
//> Data number: 2     BarsBack: 1
//> Data number: 3     BarsBack: 5
//> Data number: 3     BarsBack: 4
//> Data number: 3     BarsBack: 3
//> Data number: 3     BarsBack: 2
//> Data number: 3     BarsBack: 1

The outer for-to loop begins with dataNum having a value of 1 and continues till 3 for a total of 3 loop cycles. The inner loop, a down-to loop, starts with barsBack being 5 and continues till this variable is 1 and therefore is executed 5 times.

Inside the nested loop, Print() outputs the counter variables from the outer and inner loop. In the output we can see that for each cycle of the outer loop, the inner loop is executed till completion. So when dataNum is 1, barsBack is executed from 5 till 1.

This process continues until all outer loop cycles have been completed. And when the outer loop stops, the inner loop is also not executed anymore.

Looping over historical price bars from multiple data series

Nested loops can, for example, be used to loop over historical price bars from multiple data series:


Variables:
    dataNum(0),
    barsBack(0),
    avgDataSeries(0),
    totalAverage(0);

avgDataSeries = 0;
totalAverage  = 0;

for dataNum = 1 to 3 begin 

    for barsBack = 5 downto 1 begin 

        avgDataSeries = avgDataSeries + Close[barsBack] Data(dataNum);
        totalAverage  = totalAverage + Close[barsBack] Data(dataNum);

    end;

    avgDataSeries = avgDataSeries / 5;

    Print("Average of data series ", NumToStr(dataNum, 0), 
        " is ", NumToStr(avgDataSeries, 7));

    avgDataSeries = 0;

end;

totalAverage = totalAverage / 15;

Print("Average of all 15 bars from Data 1, 2, and 3 = ",
    NumToStr(totalAverage, 7));

//> Average of data series 1 is 1.2645320
//> Average of data series 2 is 0.7866680
//> Average of data series 3 is 0.9773620
//> Average of all 15 bars from Data 1, 2, and 3 = 1.0095207

The outer for-to loop and the inner down-to loop are identical to the previous example. New is the code to calculate the average of 5 bars from a data series (avgDataSeries) and the average of all 15 price bars from all 3 data series (totalAverage).

Both of these variables are summed in the inner loop. The data series average is calculated inside the outer loop by dividing avgDataSeries with 5. This variable is then outputted with Print() and reset to 0 for the next completion of the inner loop.

The total average is calculated when both loops are done by dividing totalAverage with 15.

Summary

A nested loop is a loop that is contained inside the body of another loop. With two loops, the nested loop is called the inner loop and the other loop the outer loop. The inner loop is executed to completion for each loop cycle of the outer loop.


References

Liberty, J. & Cadenhead, R. (2011). Sams Teach Yourself C++ in 24 Hours. IN (USA): Sams/Pearson Education.

Sempf, B., Sphar, C., & Davis, S.R. (2010). C# 2010 All-In-One for Dummies. Hoboken, NJ: John Wiley & Sons.

Stellman, A. & Greene, J. (2010). Head First C#: A Brain-Friendly Guide (2nd edition). Sebastopol, CA: O’Reilly Media.