'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 }); })(); }); });