stock-indicators/test/indicator/bollinger-bands.js
2025-03-31 11:20:04 +02:00

113 lines
2.9 KiB
JavaScript
Executable File

'use strict';
import chai from 'chai';
const assert = chai.assert;
import BB from '../../lib/indicator/bollinger-bands.js';
describe('Boilinger Bands', () => {
let data = [25.5, 26.75, 27.0, 26.5, 27.25];
let data_2 = [25.5, 26.75, 27.0, 26.5, 27.25, 28.1];
it('should calculate correctly and return result', () => {
let runTest = async (periods, values, expectedResult) => {
let opts = { periods, lazyEvaluation: true, sliceOffset: true };
let bb = new BB(opts);
bb.setValues(values);
let results = await bb.calculate();
assert.isArray(results)
assert.isTrue(values.length - opts.periods + 1 == results.length);
expectedResult.forEach((expected, idx) => {
let resultItem = results[idx];
assert.isObject(resultItem);
assert.containsAllKeys(resultItem, ['upper', 'middle', 'lower', 'price']);
assert.closeTo(resultItem.upper, expected.u, 0.1);
assert.closeTo(resultItem.middle, expected.m, 0.1);
assert.closeTo(resultItem.lower, expected.l, 0.1);
assert.isTrue(resultItem.price == values[periods - 1 + idx]);
});
};
let arr = [
{
p: 5, v: data, e: [
{ m: 26.6, u: 27.8, l: 25.4 }
]
},
{
p: 5, v: data_2, e: [
{ m: 26.6, u: 27.8, l: 25.4 },
{ m: 27.1, u: 28.2, l: 26.0 }
]
},
];
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
runTest(item.p, item.v, item.e);
}
});
it('should calculate correctly and return results with offset', () => {
let runTest = async (periods, values, expectedResult) => {
let opts = { periods, sliceOffset: false, lazyEvaluation: true };
let bb = new BB(opts);
bb.setValues(values);
let results = await bb.calculate();
assert.isArray(results)
assert.isTrue(values.length == results.length);
expectedResult.forEach((expected, idx) => {
let resultItem = results[idx];
assert.containsAllKeys(resultItem, ['upper', 'middle', 'lower', 'price']);
assert.closeTo(resultItem.upper, expected.u, 0.1);
assert.closeTo(resultItem.middle, expected.m, 0.1);
assert.closeTo(resultItem.lower, expected.l, 0.1);
assert.isTrue(resultItem.price == values[idx]);
});
};
let arr = [
{
p: 5, v: data, e: [
{ m: 0, u: 0, l: 0 },
{ m: 0, u: 0, l: 0 },
{ m: 0, u: 0, l: 0 },
{ m: 0, u: 0, l: 0 },
{ m: 26.6, u: 27.8, l: 25.4 }
]
}
];
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
runTest(item.p, item.v, item.e);
}
});
it('should throw error on invalid options', () => {
function runTest(opts) {
let bb = new BB(opts);
bb.setValues(data);
assert.throws(() => bb.calculate(), Error);
};
[
{ periods: data.length + 1 },
{ startIndex: data.length + 1 },
{ endIndex: data.length + 1 },
{ periods: 'foo' },
{ startIndex: data.length, endIndex: 0 },
].forEach((option) => runTest(option));
});
});