stock-indicators/test/indicator/average-directional-index.js
2025-03-31 11:20:04 +02:00

151 lines
6.2 KiB
JavaScript
Executable File

'use strict';
import chai from 'chai';
const assert = chai.assert;
import _ from 'underscore';
import ADI from '../../lib/indicator/average-directional-index.js';
describe('Average Directional Index', () => {
let data = [
//high, low, close
[30.20, 29.41, 29.87],
[30.28, 29.32, 30.24],
[30.45, 29.96, 30.10],
[29.35, 28.74, 28.90],
[29.35, 28.56, 28.92],
[29.29, 28.41, 28.48],
[28.83, 28.08, 28.56],
[28.73, 27.43, 27.56],
[28.67, 27.66, 28.47],
[28.85, 27.83, 28.28],
[28.64, 27.40, 27.49],
[27.68, 27.09, 27.23],
[27.21, 26.18, 26.35],
[26.87, 26.13, 26.33],
[27.41, 26.63, 27.03],
[26.94, 26.13, 26.22],
[26.52, 25.43, 26.01],
[26.52, 25.35, 25.46],
[27.09, 25.88, 27.03],
[27.69, 26.96, 27.45],
[28.45, 27.14, 28.36],
[28.53, 28.01, 28.43],
[28.67, 27.88, 27.95],
[29.01, 27.99, 29.01],
[29.87, 28.76, 29.38],
[29.80, 29.14, 29.36],
[29.75, 28.71, 28.91],
[30.65, 28.93, 30.61],
[30.60, 30.03, 30.05],
[30.76, 29.39, 30.19],
[31.17, 30.14, 31.12],
];
let expectedResults = [
//TR +DM 1 -DM 1 TR14 +DM14 -DM14 +DI14 -DI14 DI14DiffDI14Sum DX ADX
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.96, 0.00, 0.09, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.48, 0.17, 0.00, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.36, 0.00, 1.22, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.79, 0.00, 0.19, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.88, 0.00, 0.15, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.75, 0.00, 0.33, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.31, 0.00, 0.65, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.11, 0.00, 0.00, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.02, 0.19, 0.00, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.24, 0.00, 0.44, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.58, 0.00, 0.31, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.05, 0.00, 0.91, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0.73, 0.00, 0.05, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1.08, 0.54, 0.00, 13.33, 0.90, 4.32, 6.75, 32.42, 25.67, 39.17, 65.54, 0],
[0.90, 0.00, 0.49, 13.28, 0.84, 4.51, 6.29, 33.95, 27.65, 40.24, 68.73, 0],
[1.09, 0.00, 0.70, 13.42, 0.78, 4.89, 5.78, 36.43, 30.65, 42.21, 72.60, 0],
[1.17, 0.00, 0.08, 13.63, 0.72, 4.62, 5.29, 33.89, 28.60, 39.17, 73.01, 0],
[1.63, 0.57, 0.00, 14.29, 1.24, 4.29, 8.70, 30.02, 21.32, 38.71, 55.06, 0],
[0.72, 0.59, 0.00, 13.99, 1.75, 3.98, 12.49, 28.47, 15.98, 40.96, 39.01, 0],
[1.31, 0.76, 0.00, 14.30, 2.38, 3.70, 16.68, 25.87, 9.19, 42.55, 21.60, 0],
[0.51, 0.08, 0.00, 13.79, 2.29, 3.43, 16.63, 24.90, 8.27, 41.53, 19.92, 0],
[0.78, 0.14, 0.00, 13.59, 2.27, 3.19, 16.69, 23.47, 6.78, 40.16, 16.87, 0],
[1.06, 0.35, 0.00, 13.67, 2.45, 2.96, 17.93, 21.65, 3.72, 39.59, 9.40, 0],
[1.11, 0.86, 0.00, 13.80, 3.14, 2.75, 22.73, 19.92, 2.81, 42.64, 6.59, 0],
[0.66, 0.00, 0.00, 13.48, 2.91, 2.55, 21.61, 18.94, 2.67, 40.55, 6.59, 0],
[1.04, 0.00, 0.43, 13.56, 2.71, 2.80, 19.95, 20.64, 0.68, 40.59, 1.69, 0],
[1.74, 0.90, 0.00, 14.33, 3.41, 2.60, 23.82, 18.13, 5.69, 41.94, 13.57, 33.58],
[0.58, 0.00, 0.00, 13.89, 3.17, 2.41, 22.81, 17.36, 5.45, 40.18, 13.57, 32.15],
[1.38, 0.00, 0.64, 14.28, 2.94, 2.88, 20.61, 20.20, 0.41, 40.81, 1.01, 29.93],
[1.03, 0.41, 0.00, 14.29, 3.14, 2.68, 21.97, 18.74, 3.23, 40.70, 7.93, 28.36],
];
let convertArrayToCollection = (data) => {
return data.map(item => {
return { high: item[0], low: item[1], close: item[2] };
});
};
let convertExpectedResultsToCollection = (data) => {
return data.map(item => {
return { tr: item[0], pdm: item[1], ndm: item[2], trPeriod: item[3], pdmPeriod: item[4], ndmPeriod: item[5], pdi: item[6], ndi: item[7], dx: item[10], adx: item[11] };
});
};
let runTest = async (d, e, opts = {}) => {
let adi = new ADI(opts);
adi.setValues(d);
let results = await adi.calculate();
assert.isArray(results);
assert.isTrue(results.length == e.length);
results.forEach((resultItem, idx) => {
assert.isObject(resultItem);
let expectedResultItem = e[idx];
assert.closeTo(resultItem.tr, expectedResultItem.tr, 0.1);
assert.closeTo(resultItem.pdm, expectedResultItem.pdm, 0.1);
assert.closeTo(resultItem.ndm, expectedResultItem.ndm, 0.1);
assert.closeTo(resultItem.trPeriod, expectedResultItem.trPeriod, 0.1);
assert.closeTo(resultItem.pdmPeriod, expectedResultItem.pdmPeriod, 0.1);
assert.closeTo(resultItem.ndmPeriod, expectedResultItem.ndmPeriod, 0.1);
assert.closeTo(resultItem.pdi, expectedResultItem.pdi, 0.1);
assert.closeTo(resultItem.ndi, expectedResultItem.ndi, 0.1);
assert.closeTo(resultItem.dx, expectedResultItem.dx, 0.4);
assert.closeTo(resultItem.adx, expectedResultItem.adx, 0.4);
});
}
it('should calculate correctly and return result', () => {
let d = convertArrayToCollection(data);
let e = convertExpectedResultsToCollection(expectedResults);
(async () => {
runTest(d, e, { sliceOffset: false });
})();
});
it('should calculate correctly with options and return result', () => {
let dataCopy = [...data];
dataCopy.unshift([30.30, 29.40, 29.80]);
dataCopy.push([30.20, 29.41, 29.87]);
let d = convertArrayToCollection(dataCopy);
let e = convertExpectedResultsToCollection(expectedResults);
let opts = { startIndex: 1, endIndex: d.length - 2, sliceOffset: false };
(async () => {
runTest(d, e, opts);
})();
});
it('should calculate correctly with sliceOffset and return result', () => {
let d = convertArrayToCollection(data);
let e = convertExpectedResultsToCollection(expectedResults);
e = e.slice(27);
(async () => {
runTest(d, e, { sliceOffset: true });
})();
});
});