# Financial oscillators
Derive source-aligned RSI, MACD, and stochastic values with explicit gap resets.

## APIs demonstrated

- [relativeStrengthIndex](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [movingAverageConvergenceDivergence](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [stochasticOscillator](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [RelativeStrengthIndexPoint](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [MovingAverageConvergenceDivergencePoint](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [StochasticOscillatorPoint](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [OscillatorOptions](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [RelativeStrengthIndexOptions](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [MovingAverageConvergenceDivergenceOptions](/reference/functions/financial-series/) from `@pibbl/core/viz`
- [StochasticOscillatorOptions](/reference/functions/financial-series/) from `@pibbl/core/viz`

## Complete example

[Plain source](/minimal/viz/financial-oscillators.tsx). Run as a browser module after the document body exists. TSX uses `jsx: "react-jsx"` and `jsxImportSource: "@pibbl/core"`.

```tsx
import { FocusManagement, Text, pibbl } from "@pibbl/core";
import {
  movingAverageConvergenceDivergence,
  relativeStrengthIndex,
  stochasticOscillator,
  type MovingAverageConvergenceDivergencePoint,
  type MovingAverageConvergenceDivergenceOptions,
  type OscillatorOptions,
  type RelativeStrengthIndexPoint,
  type RelativeStrengthIndexOptions,
  type StochasticOscillatorOptions,
  type StochasticOscillatorPoint,
} from "@pibbl/core/viz";

const prices = [
  { high: 103, low: 99, close: 100 },
  { high: 105, low: 100, close: 104 },
  { high: 106, low: 102, close: 103 },
  { high: 108, low: 102, close: 107 },
];
const closing: OscillatorOptions<(typeof prices)[number]> = { value: "close" };
const rsiOptions: RelativeStrengthIndexOptions<(typeof prices)[number]> = {
  ...closing,
  period: 2,
};
const rsi: readonly RelativeStrengthIndexPoint<(typeof prices)[number]>[] =
  relativeStrengthIndex(prices, rsiOptions);
const macdOptions: MovingAverageConvergenceDivergenceOptions<
  (typeof prices)[number]
> = {
  ...closing,
  fastPeriod: 2,
  slowPeriod: 3,
  signalPeriod: 2,
};
const macd: readonly MovingAverageConvergenceDivergencePoint<
  (typeof prices)[number]
>[] = movingAverageConvergenceDivergence(prices, macdOptions);
const stochasticOptions: StochasticOscillatorOptions<(typeof prices)[number]> =
  {
    high: "high",
    low: "low",
    close: "close",
    lookbackPeriod: 2,
    kPeriod: 1,
    dPeriod: 2,
  };
const stochastic: readonly StochasticOscillatorPoint<
  (typeof prices)[number]
>[] = stochasticOscillator(prices, stochasticOptions);

export default function mount(canvas: HTMLCanvasElement) {
  const last = prices.length - 1;
  return pibbl(
    canvas,
    <FocusManagement>
      <Text
        style={{ left: 16, top: 18, font: "12px sans-serif", fill: "#18283d" }}
      >
        {`RSI ${rsi[last]!.rsi} · MACD ${macd[last]!.macd} · %K ${stochastic[last]!.k}`}
      </Text>
    </FocusManagement>,
  );
}

const canvas = document.createElement("canvas");
canvas.width = 320;
canvas.height = 220;
document.body.append(canvas);
const app = mount(canvas);
window.addEventListener("pagehide", () => app.dispose(), { once: true });

```

## Usage notes



## Documentation version

Documentation built with @pibbl/core 0.0.2, revision dd39ce2. ALPHA — NOT FOR PRODUCTION USE.
