Skip to main content

Agent-friendly CLI for Taiwan Stock Exchange (TWSE) and Taipei Exchange (TPEX) — stock market data, one tool

Project description

twstock-cli

Agent-friendly CLI for Taiwan Stock Exchange (TWSE) and Taipei Exchange (TPEX) — stock market data, one tool.

Install

uv (recommended)

uv tool install twstock-cli
uv tool install 'twstock-cli[mcp]'            # with MCP server support
uv tool install 'twstock-cli[mcp,analysis]'   # with everything

Homebrew

brew tap DeepWaveLab/twstock_cli https://github.com/DeepWaveLab/twstock_cli
brew install twstock-cli

pip

pip install twstock-cli
pip install 'twstock-cli[mcp]'            # MCP server support
pip install 'twstock-cli[analysis]'       # pandas, openpyxl, matplotlib, plotly
pip install 'twstock-cli[mcp,analysis]'   # everything

Update

# uv
uv tool upgrade twstock-cli

# Homebrew
brew update && brew upgrade twstock-cli

# pip
pip install --upgrade twstock-cli

From source

git clone https://github.com/DeepWaveLab/twstock_cli.git
cd twstock_cli
uv sync                                   # core only
uv sync --extra mcp --extra analysis      # with all extras

Quick Start

# Fetch daily stock data (all stocks)
twstock fetch stock.stock-day-all --json

# Filter to specific fields (saves tokens)
twstock fetch stock.stock-day-all --json --fields "Code,Name,ClosingPrice"

# Filter by stock code
twstock fetch stock.stock-day-all --json --code 2330

# Get PE ratio and dividend yield
twstock fetch stock.bwibbu-all --json --code 2330

# Discover endpoints
twstock endpoints --search "股利" --json

# Inspect endpoint schema
twstock schema stock.stock-day-all --json

Commands

twstock fetch <endpoint>

Fetch data from any TWSE/TPEX endpoint.

twstock fetch stock.stock-day-all --json              # by dotted name
twstock fetch /exchangeReport/STOCK_DAY_ALL --json     # by raw API path
twstock fetch STOCK_DAY_ALL --json                     # by API code
Flag Description
--json JSON envelope output (auto-detected when piped)
--fields "Code,Name" Select specific fields
--code 2330 Filter by stock code
--limit 10 Limit records returned
--normalize Convert strings to numbers, ROC dates to ISO 8601
--ndjson Newline-delimited JSON (one record per line)
--raw Bare JSON array without envelope
--dry-run Preview request as JSON without making an HTTP call
--stdin Read parameters from JSON on stdin
--no-cache Bypass disk cache

twstock endpoints

Discover available endpoints.

twstock endpoints --json                           # list all 359
twstock endpoints --search "daily" --json          # search by keyword
twstock endpoints --category stock --json          # filter by category
twstock endpoints --search "bwibbu" --with-fields --json  # show fields

Sources: 143 TWSE OpenAPI + 9 TWSE Web API + 207 TPEX OpenAPI = 359 endpoints.

--category filter values: stock (45), company (86), broker (9), other (4), otc (64), otc_company (29), web (8). Use --search to find the remaining endpoints.

twstock schema <endpoint>

Inspect endpoint fields, inferred types, and example values.

twstock schema stock.stock-day-all --json

twstock serve

Start as an MCP (Model Context Protocol) server on stdio.

twstock serve

Exposes tools: twstock_fetch, twstock_endpoints, twstock_schema. Requires mcp extra.

twstock <command> --help-json

Output structured command metadata as JSON (flags, types, defaults).

twstock --help-json                  # list all commands
twstock fetch --help-json            # list fetch params with types
twstock stock --help-json            # list stock subcommands

--dry-run

Preview the planned request without making an HTTP call.

twstock fetch stock.stock-day-all --dry-run --fields "Code,Name" --code 2330

--stdin

Accept structured JSON input from stdin (CLI flags override stdin values).

echo '{"endpoint":"stock.stock-day-all","fields":["Code","Name"],"limit":5}' | twstock fetch --stdin --json

Output Formats

JSON envelope (default)

{"ok": true, "data": [{"Code": "2330", "Name": "台積電", "ClosingPrice": "595.00"}]}

NDJSON (--ndjson)

{"Code": "2330", "Name": "台積電", "ClosingPrice": "595.00"}
{"Code": "2317", "Name": "鴻海", "ClosingPrice": "100.50"}

Raw (--raw)

[{"Code": "2330", "Name": "台積電"}, {"Code": "2317", "Name": "鴻海"}]

Normalized (--normalize)

{"ok": true, "data": [{"Code": "2330", "ClosingPrice": 595.0, "TradeVolume": 36317450}]}

Environment Variables

Variable Values Description
TWSTOCK_OUTPUT json, human Override auto-detection of output format

Exit Codes

Code Meaning
0 Success
1 API error (TWSE returned 4xx/5xx)
2 Validation error (unknown endpoint, bad args)
3 Network error (cannot reach TWSE API)

Data Analysis & Export ([analysis] extra)

Install the analysis extra to unlock data analysis, visualization, and export capabilities.

Export to XLSX

import subprocess, json, pandas as pd

result = subprocess.run(
    ["twstock", "fetch", "stock.stock-day-all", "--json", "--fields", "Code,Name,ClosingPrice,TradeVolume", "--normalize"],
    capture_output=True, text=True,
)
data = json.loads(result.stdout)["data"]
df = pd.DataFrame(data)
df.to_excel("stock_daily.xlsx", index=False)

Visualization with matplotlib

import subprocess, json, pandas as pd, matplotlib.pyplot as plt

result = subprocess.run(
    ["twstock", "fetch", "stock.stock-day-all", "--json", "--fields", "Code,Name,ClosingPrice,TradeVolume", "--normalize", "--limit", "20"],
    capture_output=True, text=True,
)
df = pd.DataFrame(json.loads(result.stdout)["data"])
df.plot.bar(x="Name", y="TradeVolume", title="Top 20 Stocks by Volume")
plt.tight_layout()
plt.savefig("volume_chart.png")

Interactive charts with plotly

import subprocess, json, pandas as pd, plotly.express as px

result = subprocess.run(
    ["twstock", "fetch", "stock.stock-day-all", "--json", "--fields", "Code,Name,ClosingPrice,TradeVolume", "--normalize", "--limit", "30"],
    capture_output=True, text=True,
)
df = pd.DataFrame(json.loads(result.stdout)["data"])
fig = px.scatter(df, x="ClosingPrice", y="TradeVolume", hover_name="Name", title="Price vs Volume")
fig.write_html("price_vs_volume.html")

Export to PPTX

from pptx import Presentation
from pptx.util import Inches
import subprocess, json

result = subprocess.run(
    ["twstock", "fetch", "stock.stock-day-all", "--json", "--fields", "Code,Name,ClosingPrice", "--limit", "10", "--normalize"],
    capture_output=True, text=True,
)
data = json.loads(result.stdout)["data"]

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5])  # blank layout
slide.shapes.title.text = "Top 10 Stocks"

rows, cols = len(data) + 1, 3
table = slide.shapes.add_table(rows, cols, Inches(0.5), Inches(1.5), Inches(9), Inches(4)).table
for i, header in enumerate(["Code", "Name", "ClosingPrice"]):
    table.cell(0, i).text = header
for r, row in enumerate(data, 1):
    for c, key in enumerate(["Code", "Name", "ClosingPrice"]):
        table.cell(r, c).text = str(row.get(key, ""))

prs.save("stocks.pptx")

Analysis extras included

Package Purpose
pandas DataFrames, filtering, groupby, .to_excel(), .to_csv()
openpyxl XLSX read/write (powers pandas.to_excel())
matplotlib Static charts and plots
plotly Interactive HTML charts
python-pptx PowerPoint slide generation (included in core)

For AI Agents

See AGENTS.md for agent-specific instructions, workflows, and token-saving tips.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

twstock_cli-0.1.4.tar.gz (179.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

twstock_cli-0.1.4-py3-none-any.whl (40.3 kB view details)

Uploaded Python 3

File details

Details for the file twstock_cli-0.1.4.tar.gz.

File metadata

  • Download URL: twstock_cli-0.1.4.tar.gz
  • Upload date:
  • Size: 179.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for twstock_cli-0.1.4.tar.gz
Algorithm Hash digest
SHA256 f629b3c5c69e673f7c50266a6fb402c3642a54151e52d4e7ffbf514b12c53da9
MD5 8b08ea630afb31cf7f56e5fb3cc5cdae
BLAKE2b-256 c956b8c96623f5a03bef565029af67cee1a935c03f361b6827ef86ec83e1e688

See more details on using hashes here.

File details

Details for the file twstock_cli-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: twstock_cli-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 40.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for twstock_cli-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 a830958f3d4495a009ddec0f83e22881049f83f0e0e9e5a00a42fa2d9b0d59ed
MD5 8f478980a0ee8d6d28b01536500ec7fd
BLAKE2b-256 96ddb5825c9b338a2efe0040a78832eee1ff5ca67037c31e1983a1e1184295f7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page