Efficient calculation of Bollinger Bands

stuff about computer science and programming
Post Reply
User avatar
dendiz
Site Admin
Posts: 114
Joined: Wed Oct 10, 2018 3:48 am

Efficient calculation of Bollinger Bands

Post by dendiz » Wed Oct 10, 2018 9:36 pm

The Bollinger bands used in technical analysis is the +/- 2 * standard deviation of the closing price plotted on the chart.
This prices are expected to fluctuate in this band 95% of the time. As with any sliding window calculation the easy way is
to calculate everything each time for each window. Which usually means quadratic algorithm. A better way exists to calculate
the values for standard deviations using some smart manipulations on the standard deviation formula. (to be more precise the
variance formula which is the square of the standard deviation.)

To the variance formula is (k = )
1-JJdV5CFtncc3vbGL.gif
1-JJdV5CFtncc3vbGL.gif (959 Bytes) Viewed 72 times
expanding the quadratic term
2.gif
2.gif (1.51 KiB) Viewed 72 times
extracting the last constant term independent of i
3.gif
3.gif (1.58 KiB) Viewed 72 times
extract the term independent of i from the 2nd part
4.gif
4.gif (1.9 KiB) Viewed 72 times
first term and last term can be handled the way moving averages are handle. When the window slides right, add the new term
remove the old term on the left. This is efficient.
5.gif
5.gif (1.17 KiB) Viewed 72 times
so the middle term becomes
6.gif
6.gif (479 Bytes) Viewed 72 times
now the second term can also be calculated using the efficient method.

Here is an implementation in code for Bollinger bands

Code: Select all

    public SuperList<BollingerBand> calculate() {
        double totalAvg = 0d;
        double totalSq = 0d;
        int i = 0;
        SuperList<BollingerBand> result = new SuperList<>();
        for (Double value : values) {
            totalAvg += value;
            totalSq += value * value;
            if (i >= PERIOD - 1) {
                double avg = totalAvg / PERIOD;
                double stddev = Math.sqrt((totalSq - (totalAvg*totalAvg)/PERIOD)/ PERIOD);
                BollingerBand band = new BollingerBand(avg, avg + 2 * stddev, avg - 2 * stddev);
                result.add(band);
                totalAvg -= values.get(i - PERIOD + 1);
                totalSq -= values.get(i - PERIOD + 1) * values.get(i - PERIOD + 1);
            }
            i++;
        }
        return result;
    }

Post Reply