npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/api-equity-prices

v1.0.1

Published

Equity / ETF / fund price + fundamentals core interface for molecule.dev

Readme

@molecule/api-equity-prices

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Provider-agnostic equity-prices interface for molecule.dev.

Defines the EquityPricesProvider interface for stock / ETF / fund quotes, historical bars, fundamentals, and symbol search. Bond packages (Alpha Vantage, IEX Cloud, Polygon.io, etc.) implement this interface. Application code uses the convenience functions (getQuote, getHistorical, getFundamentals, searchSymbol, listSupportedExchanges) which delegate to the bonded provider.

Quotes carry an explicit ISO 4217 currency so multi-exchange callers can reconcile prices across markets. Symbols and exchange codes are kept as plain strings so providers can support whatever catalogue they expose.

Quick Start

import { setProvider, getQuote, getHistorical } from '@molecule/api-equity-prices'
import { provider as alphaVantage } from '@molecule/api-equity-prices-alpha-vantage'

setProvider(alphaVantage)
const quote = await getQuote('AAPL')
const bars = await getHistorical('AAPL', '1y')

Type

core

Installation

npm install @molecule/api-equity-prices @molecule/api-bond @molecule/api-i18n

API

Interfaces

EquityFundamentals

Optional fundamentals snapshot. All fields are optional because providers vary in coverage; consumers MUST treat missing fields as "unknown" rather than zero.

interface EquityFundamentals {
  /**
   * Equity / ETF / fund ticker symbol the fundamentals describe.
   */
  symbol: EquitySymbol

  /**
   * Market capitalization in major units of {@link currency}, if known.
   */
  marketCap?: number

  /**
   * Trailing price/earnings ratio, if known.
   */
  peRatio?: number

  /**
   * Trailing earnings per share in {@link currency}, if known.
   */
  eps?: number

  /**
   * Trailing dividend yield as a fraction (e.g. `0.012` for 1.2%), if known.
   */
  dividendYield?: number

  /**
   * Currency the monetary fundamentals are denominated in.
   */
  currency?: CurrencyCode
}

EquityHistoricalBar

A single historical price bar (close-only by default; providers may extend with OHLCV via additional optional fields if useful, but the canonical contract is { ts, close }).

interface EquityHistoricalBar {
  /**
   * Bar timestamp (period start; daily bars are conventionally midnight UTC).
   */
  ts: Date

  /**
   * Closing price for the bar in the symbol's native currency.
   */
  close: number
}

EquityPricesProvider

Equity / ETF / fund price + fundamentals provider interface.

All providers (Alpha Vantage, IEX Cloud, Polygon.io, fixtures, etc.) implement this interface. The interface is deliberately minimal so providers with very different upstream APIs can satisfy it identically.

interface EquityPricesProvider {
  /**
   * Returns the latest available quote for {@link symbol}.
   *
   * @param symbol - Ticker symbol to quote.
   * @returns Latest {@link EquityQuote}.
   */
  getQuote(symbol: EquitySymbol): Promise<EquityQuote>

  /**
   * Returns historical close-price bars for {@link symbol} over
   * {@link range}. Bars are returned in ascending chronological order.
   *
   * @param symbol - Ticker symbol to load history for.
   * @param range - Time range to cover.
   * @returns Array of {@link EquityHistoricalBar} in ascending order.
   */
  getHistorical(symbol: EquitySymbol, range: EquityHistoricalRange): Promise<EquityHistoricalBar[]>

  /**
   * Returns trailing fundamentals for {@link symbol}. Providers without
   * fundamentals coverage MAY return an object with only the {@link
   * EquityFundamentals.symbol} field populated.
   *
   * @param symbol - Ticker symbol to load fundamentals for.
   * @returns snapshot.
   */
  getFundamentals(symbol: EquitySymbol): Promise<EquityFundamentals>

  /**
   * Searches the provider's symbol catalogue for matches against
   * {@link query} (matched against ticker and/or company name).
   *
   * @param query - Free-text search string.
   * @returns Array of {@link EquitySymbolMatch}, possibly empty.
   */
  searchSymbol(query: string): Promise<EquitySymbolMatch[]>

  /**
   * Lists the exchanges this provider currently supports. Used by callers
   * to determine which markets they can query.
   *
   * @returns Array of exchange identifiers (e.g. `'NASDAQ'`, `'NYSE'`).
   */
  listSupportedExchanges(): Promise<ExchangeCode[]>
}

EquityQuote

A single point-in-time equity price quote.

interface EquityQuote {
  /**
   * Equity / ETF / fund ticker symbol.
   */
  symbol: EquitySymbol

  /**
   * Latest traded price (or last close if market is closed), expressed in
   * {@link currency} as a plain `number` (major units, e.g. dollars).
   */
  price: number

  /**
   * ISO 4217 currency code the {@link price} is denominated in.
   */
  currency: CurrencyCode

  /**
   * Timestamp the quote was observed.
   */
  ts: Date

  /**
   * Exchange the symbol is listed on. Optional — not every provider exposes
   * the exchange consistently.
   */
  exchange?: ExchangeCode
}

EquitySymbolMatch

A symbol-search result row.

interface EquitySymbolMatch {
  /**
   * Ticker symbol.
   */
  symbol: EquitySymbol

  /**
   * Human-readable security name (e.g. `'Apple Inc.'`).
   */
  name: string

  /**
   * Exchange the symbol is listed on, if known.
   */
  exchange?: ExchangeCode

  /**
   * Currency the security trades in, if known.
   */
  currency?: CurrencyCode
}

Types

CurrencyCode

ISO 4217 three-letter currency code (e.g. 'USD', 'EUR', 'JPY').

Quotes from a provider may be denominated in any currency the underlying exchange supports.

type CurrencyCode = string

EquityHistoricalRange

Supported historical price ranges.

Providers SHOULD support at least '1d', '1m', and '1y'. Providers MAY throw {@link Error} if a requested range is not supported.

type EquityHistoricalRange = '1d' | '5d' | '1m' | '3m' | '6m' | '1y' | '5y' | 'max'

EquitySymbol

Equity / ETF / fund symbol ticker (e.g. 'AAPL', 'VOO', 'SPY').

Kept as a plain string alias rather than a string-literal union so providers can support whatever set of symbols / exchanges they expose. Use {@link EquityPricesProvider.searchSymbol} to discover what a given provider supports at runtime.

type EquitySymbol = string

ExchangeCode

Exchange identifier (e.g. 'NASDAQ', 'NYSE', 'LSE', 'TSE').

Plain string for the same reason as {@link EquitySymbol} — providers differ widely on which exchanges they cover.

type ExchangeCode = string

Functions

getFundamentals(symbol)

Returns trailing fundamentals for {@link symbol} using the bonded provider.

function getFundamentals(symbol: string): Promise<EquityFundamentals>
  • symbol — Ticker symbol to load fundamentals for.

Returns: snapshot.

getHistorical(symbol, range)

Returns historical close-price bars for {@link symbol} over {@link range} using the bonded provider. Bars are returned in ascending chronological order.

function getHistorical(symbol: string, range: EquityHistoricalRange): Promise<EquityHistoricalBar[]>
  • symbol — Ticker symbol to load history for.
  • range — Time range to cover.

Returns: Array of {@link EquityHistoricalBar} in ascending order.

getProvider()

Retrieves the bonded equity-prices provider, throwing if none is configured.

function getProvider(): EquityPricesProvider

Returns: The bonded equity-prices provider.

getQuote(symbol)

Returns the latest available quote for {@link symbol} using the bonded provider.

function getQuote(symbol: string): Promise<EquityQuote>
  • symbol — Ticker symbol to quote.

Returns: Latest {@link EquityQuote}.

hasProvider()

Checks whether an equity-prices provider is currently bonded.

function hasProvider(): boolean

Returns: true if an equity-prices provider is bonded.

listSupportedExchanges()

Lists the exchanges the bonded provider currently supports.

function listSupportedExchanges(): Promise<string[]>

Returns: Array of exchange identifiers.

searchSymbol(query)

Searches the bonded provider's symbol catalogue for matches against {@link query}.

function searchSymbol(query: string): Promise<EquitySymbolMatch[]>
  • query — Free-text search string.

Returns: Array of {@link EquitySymbolMatch}, possibly empty.

setProvider(provider)

Registers an equity-prices provider as the active singleton. Called by bond packages (e.g. @molecule/api-equity-prices-alpha-vantage) during application startup.

function setProvider(provider: EquityPricesProvider): void
  • provider — The equity-prices provider implementation to bond.

Available Providers

| Provider | Package | | --------------------------- | ------------------------------------------- | | Alpha Vantage Equity Prices | @molecule/api-equity-prices-alpha-vantage | | IEX Cloud | @molecule/api-equity-prices-iex | | Polygon.io Equity Prices | @molecule/api-equity-prices-polygon |

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1
  • @molecule/api-i18n ^1.0.1

Runtime Dependencies

  • @molecule/api-bond

  • @molecule/api-i18n

  • Server-side only. Provider API keys are secrets; fetch quotes in API handlers/jobs and serve the UI through the app's own endpoints.

  • Cache aggressively. Free market-data tiers are severely rate-limited (some to a few dozen calls per DAY) — a getQuote() per page render exhausts the quota. Cache quotes server-side and refresh on an interval, not per request.

  • Symbols and exchanges are provider catalogues, not universal. Resolve user input through searchSymbol() instead of assuming a ticker exists, and store what the provider returned.

  • EquityFundamentals fields are optional by contract — treat a missing field as "unknown", never as zero (an absent P/E is not a 0 P/E).

  • Quotes carry an explicit ISO 4217 currency — format prices with it; never hardcode $.

  • getHistorical(symbol, range) takes an enum range ('1d''5y', 'max'); bars return in ascending chronological order.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • [ ] A known ticker (e.g. getQuote('AAPL')) renders a PLAUSIBLE quote in the UI — a real price in a sane range, formatted with the quote's own currency (never a hardcoded $), never 0 / null / NaN or a spinner that never resolves.
  • [ ] Several distinct tickers (e.g. AAPL and MSFT) each render their OWN price — not one shared placeholder or the same number repeated (a stale-cache or wrong-symbol wiring bug).
  • [ ] If the app charts history, getHistorical(symbol, range) returns an ascending series of { ts, close } that actually draws a line that moves — not an empty array, a flat line, or points in reversed order.
  • [ ] An invalid / unknown ticker resolves to a clear "not found" in the UI (empty searchSymbol() results, or a caught getQuote error) — never a crash, a blank card, or a NaN price.
  • [ ] Staleness is honest: the quote's ts is surfaced (a timestamp or a "delayed / last close" label) so an out-of-hours last-close price is NOT presented as a live trade — the UI never dresses stale data up as real-time.
  • [ ] A provider rate-limit / outage (free tiers cap at a few calls) degrades gracefully to last-known-cached data or an empty state with a message — never a crashed page or a NaN; quotes are cached server-side, not refetched per render.
  • [ ] The provider API key stays server-side: quotes are served only through the app's own authenticated endpoint, scoped to specific symbols — not an open, unbounded proxy any caller can pass arbitrary tickers/params to.