diff --git a/src/indicator/volatility/bollingerBands.test.ts b/src/indicator/volatility/bollingerBands.test.ts new file mode 100644 index 0000000..ea10c65 --- /dev/null +++ b/src/indicator/volatility/bollingerBands.test.ts @@ -0,0 +1,40 @@ +// Copyright (c) 2022 Onur Cinar. All Rights Reserved. +// https://github.com/cinar/indicatorts + +import { deepStrictEqual } from 'assert'; +import { roundDigitsAll } from '../../helper/numArray'; +import { bollingerBands } from './bollingerBands'; + +describe('Bollinger Bands', () => { + it('should be able to compute the bollinger bands', () => { + const closings = [ + 2, 4, 6, 8, 12, 14, 16, 18, 20, 2, 4, 6, 8, 12, 14, 16, 18, 20, 2, 4, 6, + 8, 12, 14, 16, 18, 20, 2, 4, 6, 8, 12, 14, 16, 18, 20, + ]; + + const expectedUpperBand = [ + 2, 3, 4, 5, 6.4, 7.67, 8.86, 10, 11.11, 10.2, 9.64, 9.33, 9.23, 9.43, + 9.73, 10.13, 10.59, 11.11, 10.63, 22.78, 22.56, 22.45, 22.56, 22.84, + 23.22, 23.72, 24.32, 23.9, 22.78, 22.56, 22.45, 22.56, 22.84, 23.22, + 23.72, 24.32, + ]; + + const expectedMiddleBand = [ + 2, 3, 4, 5, 6.4, 7.67, 8.86, 10, 11.11, 10.2, 9.64, 9.33, 9.23, 9.43, + 9.73, 10.13, 10.59, 11.11, 10.63, 10.3, 10.5, 10.7, 11, 11.3, 11.5, 11.7, + 11.9, 11.1, 10.3, 10.5, 10.7, 11, 11.3, 11.5, 11.7, 11.9, + ]; + + const expectedLowerBand = [ + 2, 3, 4, 5, 6.4, 7.67, 8.86, 10, 11.11, 10.2, 9.64, 9.33, 9.23, 9.43, + 9.73, 10.13, 10.59, 11.11, 10.63, -2.18, -1.56, -1.05, -0.56, -0.24, + -0.22, -0.32, -0.52, -1.7, -2.18, -1.56, -1.05, -0.56, -0.24, -0.22, + -0.32, -0.52, + ]; + + const actual = bollingerBands(closings); + deepStrictEqual(roundDigitsAll(2, actual.upperBand), expectedUpperBand); + deepStrictEqual(roundDigitsAll(2, actual.middleBand), expectedMiddleBand); + deepStrictEqual(roundDigitsAll(2, actual.lowerBand), expectedLowerBand); + }); +}); diff --git a/src/indicator/volatility/mstd.test.ts b/src/indicator/volatility/mstd.test.ts index 1ab813a..6514be5 100644 --- a/src/indicator/volatility/mstd.test.ts +++ b/src/indicator/volatility/mstd.test.ts @@ -8,8 +8,8 @@ import { mstd } from './mstd'; describe('Standard deviation', () => { it('should be able to compute std', () => { const values = [2, 4, 6, 8, 12, 14, 16, 18, 20]; - const expected = [0, 0, 0, 2.236, 2.958, 3.162, 2.958, 2.236, 2.236]; - const period = 4; + const expected = [0, 1, 1, 1, 2, 1, 1, 1, 1]; + const period = 2; const actual = mstd(period, values); deepStrictEqual(roundDigitsAll(3, actual), expected); diff --git a/src/indicator/volatility/mstd.ts b/src/indicator/volatility/mstd.ts index 84f107d..6e142bd 100644 --- a/src/indicator/volatility/mstd.ts +++ b/src/indicator/volatility/mstd.ts @@ -1,6 +1,8 @@ // Copyright (c) 2022 Onur Cinar. All Rights Reserved. // https://github.com/cinar/indicatorts +import { sma } from '../trend/sma'; + /** * Moving strandard deviation function. * @@ -10,27 +12,19 @@ */ export function mstd(period: number, values: number[]): number[] { const result = new Array(values.length); - - let sum = 0; + const averages = sma(period, values); for (let i = 0; i < values.length; i++) { - sum += values[i]; + result[i] = 0; if (i >= period - 1) { - if (i >= period) { - sum -= values[i - period]; - } - - const average = sum / period; - let ss = 0; + let sum = 0; - for (let j = 0; j < period; j++) { - ss += Math.pow(values[i - j] - average, 2); + for (let k = i - (period - 1); k <= i; k++) { + sum += (values[k] - averages[i]) * (values[k] - averages[i]); } - result[i] = Math.sqrt(ss / period); - } else { - result[i] = 0; + result[i] = Math.sqrt(sum / period); } }