UNPKG

@c9up/technical-indicators-napi

Version:

A Rust-based indicator and Charts library compiled to napi.

159 lines (135 loc) 6.04 kB
import { test } from '@japa/runner' import pkg from '../../index.js' const { anchoredRegressionStatic, anchoredRegressionRolling } = pkg import { generateTestData } from './lib.mjs' test.group('Anchored Regression', (group) => { let prices group.setup(() => { const data = generateTestData(100) prices = data.map((d) => d.close) }) // anchoredRegressionStatic test('anchoredRegressionStatic fitted has same length as input', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20) assert.lengthOf(result.fitted, prices.length) }) test('anchoredRegressionStatic upperBand has same length as input', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20) assert.lengthOf(result.upperBand, prices.length) }) test('anchoredRegressionStatic lowerBand has same length as input', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20) assert.lengthOf(result.lowerBand, prices.length) }) test('anchoredRegressionStatic slopes has same length as input', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20) assert.lengthOf(result.slopes, prices.length) }) test('anchoredRegressionStatic segments cover all bars', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20) assert.isArray(result.segments) const coveredIndices = new Set() for (const segment of result.segments) { for (let i = segment.startIndex; i <= segment.endIndex; i++) { coveredIndices.add(i) } } for (let i = 0; i < prices.length; i++) { assert.isTrue(coveredIndices.has(i), `Bar ${i} not covered by any segment`) } }) test('anchoredRegressionStatic upperBand >= fitted >= lowerBand where values are not NaN', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20) for (let i = 0; i < prices.length; i++) { const u = result.upperBand[i] const f = result.fitted[i] const l = result.lowerBand[i] if (!isNaN(u) && !isNaN(f) && !isNaN(l)) { assert.isAtLeast(u, f, `upperBand[${i}] should be >= fitted[${i}]`) assert.isAtLeast(f, l, `fitted[${i}] should be >= lowerBand[${i}]`) } } }) test('anchoredRegressionStatic anchorPeriod less than 2 throws', ({ assert }) => { try { anchoredRegressionStatic(prices, 1) assert.fail('Expected an error to be thrown') } catch (error) { assert.instanceOf(error, Error) } }) test('anchoredRegressionStatic empty data throws', ({ assert }) => { try { anchoredRegressionStatic([], 20) assert.fail('Expected an error to be thrown') } catch (error) { assert.instanceOf(error, Error) } }) test('anchoredRegressionStatic accepts optional bandMult', ({ assert }) => { const result = anchoredRegressionStatic(prices, 20, 2.0) assert.lengthOf(result.fitted, prices.length) }) // anchoredRegressionRolling test('anchoredRegressionRolling fitted has same length as input', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20) assert.lengthOf(result.fitted, prices.length) }) test('anchoredRegressionRolling upperBand has same length as input', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20) assert.lengthOf(result.upperBand, prices.length) }) test('anchoredRegressionRolling lowerBand has same length as input', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20) assert.lengthOf(result.lowerBand, prices.length) }) test('anchoredRegressionRolling slopes has same length as input', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20) assert.lengthOf(result.slopes, prices.length) }) test('anchoredRegressionRolling segments cover all bars', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20) assert.isArray(result.segments) const coveredIndices = new Set() for (const segment of result.segments) { for (let i = segment.startIndex; i <= segment.endIndex; i++) { coveredIndices.add(i) } } for (let i = 0; i < prices.length; i++) { assert.isTrue(coveredIndices.has(i), `Bar ${i} not covered by any segment`) } }) test('anchoredRegressionRolling upperBand >= fitted >= lowerBand where values are not NaN', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20) for (let i = 0; i < prices.length; i++) { const u = result.upperBand[i] const f = result.fitted[i] const l = result.lowerBand[i] if (!isNaN(u) && !isNaN(f) && !isNaN(l)) { assert.isAtLeast(u, f, `upperBand[${i}] should be >= fitted[${i}]`) assert.isAtLeast(f, l, `fitted[${i}] should be >= lowerBand[${i}]`) } } }) test('anchoredRegressionRolling anchorPeriod less than 2 throws', ({ assert }) => { try { anchoredRegressionRolling(prices, 1) assert.fail('Expected an error to be thrown') } catch (error) { assert.instanceOf(error, Error) } }) test('anchoredRegressionRolling empty data throws', ({ assert }) => { try { anchoredRegressionRolling([], 20) assert.fail('Expected an error to be thrown') } catch (error) { assert.instanceOf(error, Error) } }) test('anchoredRegressionRolling accepts optional bandMult', ({ assert }) => { const result = anchoredRegressionRolling(prices, 20, 1.5) assert.lengthOf(result.fitted, prices.length) }) })