UNPKG

@c9up/technical-indicators-napi

Version:

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

112 lines (101 loc) 3.98 kB
import { test } from '@japa/runner' import pkg from '../../index.js' const { stochasticOscillator } = pkg import { generateTestData } from './lib.mjs' test.group('StochasticOscillator', (group) => { test('valid input with 100 bars and period 14 returns array of correct length', ({ assert }) => { const data = generateTestData(100) const period = 14 const result = stochasticOscillator(data, period) // Output length = closes.length - period + 1 assert.lengthOf(result, 100 - period + 1) }) test('all values are between 0 and 100 for random market data', ({ assert }) => { const data = generateTestData(100) const result = stochasticOscillator(data, 14) result.forEach((value) => { assert.isAtLeast(value, 0) assert.isAtMost(value, 100) }) }) test('flat prices (all equal high/low/close) return 50 for all values', ({ assert }) => { // When highest_high === lowest_low, range is 0 and the Rust impl returns 50.0 const flatData = Array.from({ length: 20 }, (_, i) => ({ date: new Date(2025, 0, i + 1).toISOString().split('T')[0], open: 100.0, high: 100.0, low: 100.0, close: 100.0, volume: 1000, })) const result = stochasticOscillator(flatData, 14) result.forEach((value) => { assert.approximately(value, 50, 0.001) }) }) test('close at period high returns 100', ({ assert }) => { // Close equals the period high => %K = 100 const data = Array.from({ length: 15 }, (_, i) => ({ date: new Date(2025, 0, i + 1).toISOString().split('T')[0], open: 100.0, high: 110.0, low: 90.0, close: 110.0, volume: 1000, })) const result = stochasticOscillator(data, 14) assert.approximately(result[0], 100, 0.001) }) test('close at period low returns 0', ({ assert }) => { // Close equals the period low => %K = 0 const data = Array.from({ length: 15 }, (_, i) => ({ date: new Date(2025, 0, i + 1).toISOString().split('T')[0], open: 100.0, high: 110.0, low: 90.0, close: 90.0, volume: 1000, })) const result = stochasticOscillator(data, 14) assert.approximately(result[0], 0, 0.001) }) test('period 0 throws error', ({ assert }) => { const data = generateTestData(20) try { stochasticOscillator(data, 0) assert.fail('Expected error was not thrown') } catch (error) { assert.equal(error.message, 'Period must be greater than 0') } }) test('not enough data for the given period throws error', ({ assert }) => { const data = generateTestData(5) try { stochasticOscillator(data, 14) assert.fail('Expected error was not thrown') } catch (error) { assert.equal(error.message, 'Not enough data for the given period') } }) test('empty data throws error', ({ assert }) => { try { stochasticOscillator([], 14) assert.fail('Expected error was not thrown') } catch (error) { assert.equal(error.message, 'Not enough data for the given period') } }) test('known calculation: close midpoint of range returns ~50', ({ assert }) => { // With close exactly at midpoint of [low, high], %K = 50 const data = Array.from({ length: 15 }, (_, i) => ({ date: new Date(2025, 0, i + 1).toISOString().split('T')[0], open: 100.0, high: 110.0, low: 90.0, close: 100.0, volume: 1000, })) const result = stochasticOscillator(data, 14) assert.approximately(result[0], 50, 0.001) }) })