import type { IPrimitivePaneRenderer, IPrimitivePaneView, ISeriesApi, ISeriesPrimitive, SeriesAttachedParameter, Time, } from 'lightweight-charts'; export type FibAnchor = { logical: number; price: number; }; export type FibRetracement = { a: FibAnchor; b: FibAnchor; }; type FibLevel = { ratio: number; line: string; fill: string; }; const LEVELS: FibLevel[] = [ { ratio: 4.236, line: 'rgba(255, 45, 85, 0.95)', fill: 'rgba(255, 45, 85, 0.16)' }, { ratio: 3.618, line: 'rgba(192, 132, 252, 0.95)', fill: 'rgba(192, 132, 252, 0.14)' }, { ratio: 2.618, line: 'rgba(239, 68, 68, 0.92)', fill: 'rgba(239, 68, 68, 0.14)' }, { ratio: 1.618, line: 'rgba(59, 130, 246, 0.92)', fill: 'rgba(59, 130, 246, 0.14)' }, { ratio: 1.0, line: 'rgba(148, 163, 184, 0.92)', fill: 'rgba(59, 130, 246, 0.10)' }, { ratio: 0.786, line: 'rgba(96, 165, 250, 0.92)', fill: 'rgba(96, 165, 250, 0.10)' }, { ratio: 0.618, line: 'rgba(6, 182, 212, 0.92)', fill: 'rgba(6, 182, 212, 0.10)' }, { ratio: 0.5, line: 'rgba(34, 197, 94, 0.92)', fill: 'rgba(34, 197, 94, 0.09)' }, { ratio: 0.382, line: 'rgba(245, 158, 11, 0.92)', fill: 'rgba(245, 158, 11, 0.10)' }, { ratio: 0.236, line: 'rgba(249, 115, 22, 0.92)', fill: 'rgba(249, 115, 22, 0.10)' }, { ratio: 0.0, line: 'rgba(163, 163, 163, 0.85)', fill: 'rgba(163, 163, 163, 0.06)' }, ]; function formatRatio(r: number): string { if (Number.isInteger(r)) return String(r); const s = r.toFixed(3); return s.replace(/0+$/, '').replace(/\.$/, ''); } function formatPrice(p: number): string { if (!Number.isFinite(p)) return '—'; if (Math.abs(p) >= 1000) return p.toFixed(0); if (Math.abs(p) >= 1) return p.toFixed(2); return p.toPrecision(4); } type State = { fib: FibRetracement | null; series: ISeriesApi<'Candlestick', Time> | null; chart: SeriesAttachedParameter