SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
1.4 KB · 39 lines typescript
Raw Blame History
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