Skip to content

feat(opentypebb): native TWSE/TPEx data provider — search, quotes, key metrics, company profiles#285

Open
bakabaka0613 wants to merge 6 commits into
TraderAlice:masterfrom
bakabaka0613:feat/twse-provider
Open

feat(opentypebb): native TWSE/TPEx data provider — search, quotes, key metrics, company profiles#285
bakabaka0613 wants to merge 6 commits into
TraderAlice:masterfrom
bakabaka0613:feat/twse-provider

Conversation

@bakabaka0613

Copy link
Copy Markdown

Summary

  • Adds a native twse provider to packages/opentypebb backed by the free official open-data APIs (openapi.twse.com.tw + tpex.org.tw/openapi, no API key) — four fetchers: EquitySearch, EquityQuote, KeyMetrics (official P/E / dividend yield / P/B), EquityInfo (company profiles)
  • Symbols follow the Yahoo suffix convention (2330.TW / 6488.TWO), so the existing yfinance provider serves historical data with zero conversion; EquityHistorical is deliberately omitted (the open APIs expose no per-symbol history endpoint)
  • SymbolIndex now sources ['sec', 'twse'] (~2,400 Taiwan securities in the search index) and invalidates its cache when SOURCES changes — previously a stale cache could mask a newly added source for up to 24h
  • Unlike feat: Integrate TWSE market data tools via MCP bridge #110 (MCP-bridge approach), this stays inside the existing opentypebb provider registry — no new process, no new dependency; ROC-calendar dates and empty-string numerics are normalized at the provider boundary

Test plan

  • 36 unit tests on the pure transform logic (fixtures mirror live API shapes verified 2026-06-08, incl. halted-stock empty strings, loss-making empty P/E, full-width-space trimming)
  • 10 live integration tests against the official APIs (twse.bbProvider.spec.ts)
  • pnpm -F @traderalice/opentypebb typecheck and root npx tsc --noEmit clean
  • pnpm test — 106 files / 1851 tests pass

🤖 Generated with Claude Code

…cs, company profiles

Native twse provider backed by the free official open-data APIs (no key):

- EquitySearch: enumerate TWSE listed + TPEx OTC securities with
  Yahoo-suffixed symbols (2330.TW / 6488.TWO); English short names
  merged from t187ap03_L so English queries match
- EquityQuote: latest-day OHLCV from STOCK_DAY_ALL + tpex_mainboard_quotes
  (TPEx side includes bid/ask)
- KeyMetrics: official P/E, dividend yield, P/B from BWIBBU_ALL +
  tpex_mainboard_peratio_analysis
- EquityInfo: company profiles from t187ap03_L + mopsfin_t187ap03_O
- shared helpers (models/common.ts): ROC-date→ISO, numeric-string
  parsing (empty→null), .TW/.TWO symbol parsing, lazy per-board fetch

SymbolIndex now sources ['sec', 'twse'] and invalidates its cache when
SOURCES changes (previously a stale cache could mask a new source for
up to 24h).

EquityHistorical deliberately omitted — the open APIs expose no
per-symbol history endpoint; yfinance keeps serving .TW/.TWO history.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

@bakabaka0613 is attempting to deploy a commit to the luokerenx4's Team Team on Vercel.

A member of the Team first needs to authorize it.

bakabaka0613 and others added 5 commits June 8, 2026 11:41
TWSE/TPEx open-data hosts ban callers exceeding ~3 req/5s. Add a twseFetch()
wrapper (provider-local, not touching the shared amakeRequest) with three
layers: a URL-keyed snapshot cache (10-min TTL) plus in-flight coalescing —
the endpoints are whole-market EOD snapshots, so N symbol queries collapse to
one request per board and the cache dedupes across fetchers; a per-host
serialized throttle spacing request starts >=1.7s (the two hosts are
rate-limited independently); and bounded backoff retry, evicting failures so
they are never served from cache. All four TWSE fetchers switch from
amakeRequest to twseFetch.

Route Taiwan-listed symbols in equityGetProfile to provider 'twse' (was
hardcoded yfinance) so company profile + valuation metrics come straight from
the exchanges. isTaiwanSymbol() matches .TW/.TWO suffixes and bare numeric
listing codes. Only equityGetProfile is routed — it is the only AI-tool-
reachable surface twse can serve (getProfile=EquityInfo, getKeyMetrics=
KeyMetrics); broker quotes and financials/ratios/earnings/insider/discover
have no twse fetcher and stay on yfinance/fmp.

Verified: full pnpm test (1897), root + opentypebb tsc clean, live
twse.bbProvider integration (10).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tios

equityGetRatios uses FMP, which covers US fundamentals only and needs an
fmp_api_key; twse has no financial-ratios fetcher. For Taiwan symbols this
surfaced a raw "missing fmp_api_key" error. Short-circuit isTaiwanSymbol()
with a clear message pointing to equityGetProfile (which already returns
P/E, P/B, and dividend yield from official TWSE/TPEx data, no key needed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The historical-dividends provider model and the SDK getDividends() method
already existed, but nothing exposed them as an AI tool, so agents could
not fetch dividend/distribution history at all.

Add equityGetDividends: returns { ex_dividend_date, amount } per payout
(split-adjusted, oldest first), routed to yfinance — which covers Taiwan
ETFs/stocks well (verified 0056.TW/00878.TW/00918.TW return data) while
twse has no dividend feed. A bare Taiwan code (e.g. 0056) is normalized to
the .TW listing; an explicit .TWO selects a TPEx listing. Optional
start_date/end_date and a limit (most-recent N) round it out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant