createStocksPackage
function createStocksPackage(config?): IEnginePackage;Defined in: packages/engine/src/packages/stocks/StocksPackage.ts:54
Live stock prices, stock(TICKER), stock(TICKER) on <date>
stock(TICKER) close on <date>, stock(TICKER) volume on <date>, plus
an opt-in bare-ticker form (AAPL, AAPL on April 12, 2005, …).
Why a factory, not a constant STOCKS_PACKAGE export: unlike
Weather’s Open-Meteo, there is no free/keyless stock-quote API, every
option surveyed (Alpha Vantage, Finnhub, Twelve Data, IEX Cloud, …)
requires the HOST application to sign up for its own API key. Baking in
a specific paid provider (or worse, a hardcoded key) would either not
work out of the box for most hosts or silently commit them to a vendor
choice they didn’t make. Instead this package is an extension point
“packages are our approach, we’re providing an SDK”, a host supplies
fetchQuote/fetchHistoricalQuote (backed by whichever provider and
key THEY have) via createStocksPackage’s config argument. No
config -> every stock expression resolves to a clearly-worded
STOCKS_NOT_CONFIGURED error Value, never a faked or zero price (see
packages/finance/parselets/SalesTaxParselet.ts’s doc comment for the
same “never guess a number the caller didn’t provide” principle applied
to a different package).
Not a member of BUILTIN_PACKAGES (see packages/builtins.ts)
unconfigured, this package does nothing useful, exactly like
examples/osrs is deliberately excluded from the built-in set. A host
that wants it calls createStocksPackage({ fetchQuote, ... }) and adds
the result to their ExpressionEngine’s packages array themselves.
Ticker recognition: the function-call form stock(TICKER) is the
PRIMARY, always-reachable syntax, a bare all-caps word (“AAPL”) is
genuinely ambiguous with a variable name (:AAPL = 5 is a reasonable
thing to write), so it is never claimed unconditionally. The bare form
is available only via config.enableBareTickerRecognition, gated to a
small bundled allow-list of major tickers (MajorTickers.ts). See
normalizer/StockTickerNormalizerRule.ts’s doc comment for the full
reasoning, mirroring time/timezones/CityZones.ts’s known-table
mitigation for the same class of ambiguity.
Two separate async resolvers (stocks-current/stocks-historical,
two distinct CALL_PLUGIN indices) rather than one shared one, unlike
Weather’s single shared resolver, current-price and historical-close
lookups warrant genuinely different staleTimeMs (a live quote goes
stale in seconds; a historical close for a fixed past date never goes
stale at all), and createQueryResolver bakes staleTimeMs into the
resolver instance, not the per-call query.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
config | StocksPackageConfig |