TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { median, round } from '@rareindex/shared';23/**4 * Market depth (§25) and RareIndex spread (§26): how the current asks of ONE variant sit around its5 * valuation. Pure arithmetic on observed asking prices — asks are not transactions and never feed RIV.6 */7export interface MarketDepth {8 asks: number;9 /** asks within ±5 % / ±10 % / ±20 % of RIV (cumulative bands) */10 within5: number;11 within10: number;12 within20: number;13 belowRiv: number;14 aboveRiv: number;15 lowestAsk: number | null;16 medianAsk: number | null;17 /** (best ask − RIV) / RIV — negative = the cheapest ask is below the valuation; null without asks */18 askRivSpread: number | null;19}2021export function marketDepth(asks: Array<number | null | undefined>, riv: number | null | undefined): MarketDepth | null {22 const a = asks.filter((x): x is number => typeof x === 'number' && Number.isFinite(x) && x > 0);23 if (riv === null || riv === undefined || !(riv > 0)) return null;24 const rel = a.map((x) => (x - riv) / riv);25 const within = (b: number) => rel.filter((r) => Math.abs(r) <= b).length;26 const lowest = a.length ? Math.min(...a) : null;27 return {28 asks: a.length,29 within5: within(0.05),30 within10: within(0.1),31 within20: within(0.2),32 belowRiv: rel.filter((r) => r < 0).length,33 aboveRiv: rel.filter((r) => r > 0).length,34 lowestAsk: lowest,35 medianAsk: median(a),36 askRivSpread: lowest === null ? null : round((lowest - riv) / riv, 4),37 };38}39