Search code examples
c++algorithmwhile-loopnested-loopsmoving-average

I tried coding my own simple moving average in C++


  1. I want a function that works.
  2. I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
  3. I do know that there is long code out there for this fairly simple algorithm. Please help if you can.

Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.

If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.

The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.

void Analysis::SMA()
{

    double length;
    cout << "Enter number days for your Simple Moving Average:" << endl;
    cin >> length;
    double sum = 0;
    double a;
    while (length >= 2){
        vector<double>::iterator it;
        for (int j = 0; j < close.size(); j++){

                sum = vector1[length + j - 1] + vector1[length + j - 2];
                a = sum / length;
                vector2.push_back(a);

                vector<double>::iterator g;
                for (g = vector2.begin(); g != vector2.end(); ++g){

                    cout << "Your SMA: " << *g;
            }
        }
    }
}

Solution

  • You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.

    For example suppose you have a data set:

    4 8 1 6 9
    

    and you want to calculate a moving average with a window size of 3, then you keep a running total like this:

    iteration add subtract running-total output average
    0         4   -        4             - (not enough values yet)
    1         8   -        12            -
    2         1   -        13            13 / 3
    3         6   4        15            15 / 3
    4         9   8        16            16 / 3
    

    Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).

    So the code will be something like this:

    double runningTotal = 0.0;
    int windowSize = 3;
    for(int i = 0; i < length; i++)
    {
         runningTotal += array[i];   // add
         if(i >= windowSize)
             runningTotal -= array[i - windowSize];   // subtract
         if(i >= (windowSize - 1))  // output moving average
             cout << "Your SMA: " << runningTotal / (double)windowSize;
    }
    

    You can adapt this to use your vector data structure.