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.9 KB · 47 lines typescript
Raw Blame History
1/** Pearson correlation of daily log returns between two aligned series (§186). */2export function alignedLogReturns(a: Array<{ date: string; value: number }>, b: Array<{ date: string; value: number }>): Array<[number, number]> {3  const mb = new Map(b.map((p) => [p.date, p.value]));4  const pairs: Array<[number, number]> = [];5  let prevA: number | null = null;6  let prevB: number | null = null;7  for (const p of a) {8    const vb = mb.get(p.date);9    if (vb === undefined) continue;10    if (prevA !== null && prevB !== null && prevA > 0 && prevB > 0 && p.value > 0 && vb > 0) pairs.push([Math.log(p.value / prevA), Math.log(vb / prevB)]);11    prevA = p.value;12    prevB = vb;13  }14  return pairs;15}1617export function pearson(pairs: Array<[number, number]>): { r: number; n: number } | null {18  const n = pairs.length;19  if (n < 10) return null;20  const mx = pairs.reduce((s, p) => s + p[0], 0) / n;21  const my = pairs.reduce((s, p) => s + p[1], 0) / n;22  let sxy = 0;23  let sxx = 0;24  let syy = 0;25  for (const [x, y] of pairs) {26    sxy += (x - mx) * (y - my);27    sxx += (x - mx) ** 2;28    syy += (y - my) ** 2;29  }30  if (sxx === 0 || syy === 0) return { r: 0, n };31  return { r: Math.round((sxy / Math.sqrt(sxx * syy)) * 1000) / 1000, n };32}3334export function correlationMatrix(series: Record<string, Array<{ date: string; value: number }>>, sinceDate?: string): Array<{ a: string; b: string; r: number; n: number }> {35  const keys = Object.keys(series);36  const out: Array<{ a: string; b: string; r: number; n: number }> = [];37  for (let i = 0; i < keys.length; i++) {38    for (let j = i; j < keys.length; j++) {39      const A = sinceDate ? series[keys[i]!]!.filter((p) => p.date >= sinceDate) : series[keys[i]!]!;40      const B = sinceDate ? series[keys[j]!]!.filter((p) => p.date >= sinceDate) : series[keys[j]!]!;41      const p = pearson(alignedLogReturns(A, B));42      if (p) out.push({ a: keys[i]!, b: keys[j]!, r: i === j ? 1 : p.r, n: p.n });43    }44  }45  return out;46}47