import { describe, it } from "node:test"; import assert from "node:assert/strict"; import { buildVolumeProfile } from "../lib/volumeProfile.ts"; describe("buildVolumeProfile", () => { it("returns empty for no candles", () => { const r = buildVolumeProfile([]); assert.equal(r.bins.length, 0); assert.equal(r.totalVolume, 0); assert.equal(r.pocMid, null); }); it("returns empty for zero volume", () => { const r = buildVolumeProfile([{ h: 10, l: 9, v: 0 }]); assert.equal(r.bins.length, 0); }); it("preserves total volume across bins", () => { const candles = [ { h: 12, l: 10, v: 100 }, { h: 11, l: 9, v: 200 }, { h: 14, l: 13, v: 50 }, ]; const r = buildVolumeProfile(candles, { bins: 10 }); const sum = r.bins.reduce((a, b) => a + b.volume, 0); assert.ok(Math.abs(sum - 350) < 1e-6, `sum=${sum}`); assert.equal(r.totalVolume, 350); }); it("poc is the max volume bin mid", () => { // All volume at the high end const candles = [ { h: 20, l: 19, v: 1000 }, { h: 11, l: 10, v: 10 }, ]; const r = buildVolumeProfile(candles, { bins: 8 }); assert.ok(r.pocMid != null); const maxBin = r.bins.reduce((a, b) => (b.volume > a.volume ? b : a)); assert.equal(r.pocMid, maxBin.mid); assert.ok(r.pocMid! >= 15, `poc should sit high, got ${r.pocMid}`); }); it("sets vah/val around value area", () => { const candles = Array.from({ length: 20 }, (_, i) => ({ h: 100 + i * 0.5, l: 99 + i * 0.5, v: i === 10 ? 500 : 20, })); const r = buildVolumeProfile(candles, { bins: 16, valueAreaPct: 0.7 }); assert.ok(r.vah != null && r.val != null); assert.ok(r.vah! >= r.val!); }); });