Source

72 chart lines · 2 files · 2.0 kBBenchmark harness excluded · shared/mount.ts

Apple daily stock prices1,260 records · CSV · 92.4 kB
@charts-poc/demo-data/aapl

Selection: Complete published snapshot

Date
Date
Open
number
High
number
Low
number
Close
number
Adj Close
number
Volume
number

Yahoo! Finance@observablehq/sample-datasets@1.0.1 · revision 732c0148de74 · aapl.csv · ISC distribution; upstream source credited · SHA-256 18dc8bf6542dPinned snapshot

cases/22-bollinger-band/tanstack.ts66 lines · entry
cases/22-bollinger-band/tanstack.ts
import { areaY, defineChart, deviation, lineY, window } from '@tanstack/charts'
import { scaleLinear, scaleUtc } from 'd3-scale'
import { aapl } from '@charts-poc/demo-data/aapl'
import type { AaplRow } from '@charts-poc/demo-data/aapl'
import { tanstackMount } from '../../shared/mount'
import type { ConformanceInput, ConformanceMount } from '../../types'
import { selectBollingerData } from './selection'

interface BollingerPoint extends AaplRow {
  meanClose: number
  lowerClose: number
  upperClose: number
}

const windowSize = 20
const deviationMultiplier = 2

const definition = (input: ConformanceInput) => {
  const rows = bollingerIntervals(selectBollingerData(aapl, input.revision))

  return defineChart({
    marks: [
      areaY(rows, {
        x: 'Date',
        y1: 'lowerClose',
        y2: 'upperClose',
        fill: '#7c3aed',
        fillOpacity: 0.18,
      }),
      lineY(rows, {
        x: 'Date',
        y: 'meanClose',
        stroke: '#7c3aed',
        strokeWidth: 2.25,
      }),
    ],
    x: { scale: scaleUtc, axis: { label: 'Date' } },
    y: { scale: scaleLinear, grid: true, axis: { label: 'Apple close (USD)' } },
  })
}

export const mount: ConformanceMount = tanstackMount(
  definition,
  'Twenty-day Apple Bollinger band',
)

function bollingerIntervals(
  rows: readonly AaplRow[],
): readonly BollingerPoint[] {
  return window(rows, {
    size: windowSize,
    orderBy: 'Date',
    partial: false,
    outputs: {
      meanClose: { value: 'Close', reduce: 'mean' },
      closeDeviation: { value: 'Close', reduce: deviation },
    },
  }).map(({ closeDeviation, ...row }) => {
    const spread = closeDeviation * deviationMultiplier
    return {
      ...row,
      lowerClose: row.meanClose - spread,
      upperClose: row.meanClose + spread,
    }
  })
}
cases/22-bollinger-band/selection.ts6 lines · support
cases/22-bollinger-band/selection.ts
import type { AaplRow } from '@charts-poc/demo-data/aapl'

export function selectBollingerData(rows: readonly AaplRow[], revision = 0) {
  const offset = Math.abs(revision) % 2
  return rows.slice(offset)
}