import { describe, it, expect } from 'vitest';
import { findSwingLevels } from '../server/liq-sweep.js';
describe('findSwingLevels', () => {
// Generate simple candle data with a clear swing high/low
function makeCandles(prices) {
return prices.map((p, i) => ({
time: 1000 + i * 60000,
open: p,
high: p + 1,
low: p - 1,
close: p,
volume: 1000,
}));
}
it('returns empty array for insufficient data', () => {
expect(findSwingLevels([])).toEqual([]);
expect(findSwingLevels(null)).toEqual([]);
expect(findSwingLevels([{ high: 1, low: 0 }])).toEqual([]);
});
it('returns empty array when candles are fewer than leftBars + rightBars + 1', () => {
const candles = makeCandles([10, 11, 12, 13, 14, 15]);
// default leftBars=3, rightBars=3 → need at least 7 candles
expect(findSwingLevels(candles)).toEqual([]);
});
it('detects a swing high', () => {
// Pattern: low, rising, PEAK, falling, low
const prices = [10, 11, 12, 13, 20, 13, 12, 11, 10];
const candles = prices.map((p, i) => ({
time: 1000 + i * 60000,
open: p,
high: p + 0.5,
low: p - 0.5,
close: p,
volume: 1000,
}));
const levels = findSwingLevels(candles, 3, 3);
const highs = levels.filter(l => l.type === 'swing_high');
expect(highs.length).toBeGreaterThanOrEqual(1);
// The peak is at index 4 (price 20), so swing high should be near 20.5
expect(highs[0].price).toBeCloseTo(20.5, 0);
});
it('detects a swing low', () => {
// Pattern: high, falling, BOTTOM, rising, high
const prices = [20, 19, 18, 17, 10, 17, 18, 19, 20];
const candles = prices.map((p, i) => ({
time: 1000 + i * 60000,
open: p,
high: p + 0.5,
low: p - 0.5,
close: p,
volume: 1000,
}));
const levels = findSwingLevels(candles, 3, 3);
const lows = levels.filter(l => l.type === 'swing_low');
expect(lows.length).toBeGreaterThanOrEqual(1);
// Bottom at index 4 (price 10), so swing low should be near 9.5
expect(lows[0].price).toBeCloseTo(9.5, 0);
});
it('clusters nearby levels', () => {
// Two swing highs very close to each other should cluster
const prices = [10, 11, 12, 13, 20, 13, 12, 13, 20.01, 13, 12, 11, 10];
const candles = prices.map((p, i) => ({
time: 1000 + i * 60000,
open: p,
high: p + 0.5,
low: p - 0.5,
close: p,
volume: 1000,
}));
const levels = findSwingLevels(candles, 3, 3);
const highs = levels.filter(l => l.type === 'swing_high');
// Should be clustered into 1 level (within 0.15%)
expect(highs.length).toBeLessThanOrEqual(2);
});
it('respects custom leftBars/rightBars', () => {
// With smaller bars, more swings should be detected
const prices = [10, 15, 10, 15, 10, 15, 10];
const candles = prices.map((p, i) => ({
time: 1000 + i * 60000,
open: p,
high: p + 0.5,
low: p - 0.5,
close: p,
volume: 1000,
}));
const levels1 = findSwingLevels(candles, 1, 1);
expect(levels1.length).toBeGreaterThan(0);
});
});
📜 Git History
b873b03feat: add deploy/ops scripts, vitest config, and expanded test suite9 weeks ago
Show last diff
Loading...