# all files / technicalindicators/lib/volatility/ BollingerBands.js

100% Statements 45/45
100% Branches 10/10
100% Functions 5/5
100% Lines 43/43

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    1×
    1×
    1×
    1×

    1×

    4×
    4×
    4×
    4×

    4×

    4×

    36×
    36×

    4×
    4×
    4×
    4×
    4×
    4×
    4×
    72×
    72×
    72×
    36×
    36×
    36×
    36×
    36×

    72×

    4×

    4×
    54×
    54×
    27×

    1×
    2×
    2×
    2×
    2×

    1×
    1×

    1×
    18×

     "use strict"
    const SMA        = require('../moving_averages/SMA');
    const SD         = require('../Utils/SD');
    const nf         = require('../Utils/NumberFormatter');
    let BollingerBands;

    module.exports = BollingerBands = function(input) {

        var period = input.period
        var priceArray = input.values;
        var stdDev     = input.stdDev;
        var format     = input.format || nf;

        var sma,sd;

        this.result = [];

        sma = new SMA({period : period, values :[], format : (v) => {return v}});
        sd  = new SD({period : period, values : [], format : (v) => {return v}});

        this.generator = (function* (){
            var result;
            var tick;
            var calcSMA;
            var calcsd;
            tick = yield;
            while (true) {
                calcSMA = sma.nextValue(tick);
                calcsd  = sd.nextValue(tick);
                if(calcSMA){
                    let middle = format(calcSMA);
                    let upper = format(calcSMA + (calcsd * stdDev));
                    let lower = format(calcSMA - (calcsd * stdDev));
                    let pb = format((tick - lower) / (upper - lower));
                    result = {
                        middle : middle,
                        upper  : upper,
                        lower  : lower,
                        pb     : pb
                    }
                }
                tick = yield result;
            }
        })();

        this.generator.next();

        priceArray.forEach((tick) => {
            var result = this.generator.next(tick);
            if(result.value){
                this.result.push(result.value);
            }
        });
    };

    BollingerBands.calculate = function(input) {
        input.reversedInput ? input.values.reverse(): undefined;
        let result = (new BollingerBands(input)).result;
        input.reversedInput ? result.reverse():undefined;
        return result;
    };

    BollingerBands.prototype.getResult = function () {
        return this.result;
    };

    BollingerBands.prototype.nextValue = function (price) {
        return this.generator.next(price).value;
    };