Self-hosted service
Sinotrade/Shioaji avatar
Sinotrade/Shioaji

Shioaji gives Taiwan market access from Python or any HTTP client

Shioaji all new cross platform api for trading ( 跨平台證券交易API )

526 stars41 forksDockerfileLicense varies

At a glance

What is it?
Shioaji is Sinopac's cross-platform trading API for the Taiwan financial markets, exposing stocks, futures, options and combo orders through native Python bindings or a plain HTTP surface, with SSE streaming, a dashboard and a simulator. The API keys come from a broker account, and the certificate is what turns on order placement.
Who is it for?
Shioaji is a good fit for a developer building a Taiwan market strategy who wants one API that runs from a Python research environment and from a service written in Go or TypeScript, and for a team that wants to prototype against a simulator before trading real money.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Dockerfile, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One API, two ways in

Shioaji is a trading API provided by Sinopac that gives access to the Taiwan financial markets, and its distinguishing claim is that it is cross-language as well as cross-platform. On the Python side you use native bindings with import shioaji as sj, and the README says the integration with familiar packages such as numpy, scipy, pandas, pytorch and tensorflow is seamless for building custom trading models. On the HTTP side, any language with an HTTP client can reach it, with JavaScript and TypeScript, Go, C and C++, C#, Rust and Java and Kotlin all named. The same API surface serves both, which matters for a team whose research is in Python and whose execution is not. The product side is stocks, futures, options and combo orders, and the repository is MIT-style packaged on PyPI with a 99 percent coverage badge, a documentation site, and a Docker image that installs a pinned release.

Installing the library, the CLI or a binary

Three install paths, and the differences between them are the interesting part. The Python package is the normal route:

bash
# uv (recommended)
uv add shioaji

# pip
pip install shioaji

The version pinning advice is unusually specific. To pin a release line you would use something like uv add "shioaji==1.7.*", because PyPI keeps only the latest two patch releases of each line, and releases sharing the same first two version parts never make incompatible changes, so a line pin is always safe to upgrade within. The CLI tool is a separate install that can live alongside the library:

bash
uv tool install shioaji
# or only the CLI, on any Python version:
uv tool install shioaji-cli
shioaji --help

There is a wrinkle there, because the CLI ships in the regular wheels and the free-threaded Python 3.14t wheels do not include it, so the CLI has to be installed with a regular Python, which is what uv tool install defaults to.

The standalone installer, and how to pin a channel

The third route avoids Python entirely. On Linux and macOS a shell script is fetched and piped to sh:

bash
# Stable
curl -fsSL https://github.com/Sinotrade/Shioaji/releases/latest/download/install.sh | sh

# Pre-release
curl -fsSL https://github.com/Sinotrade/Shioaji/releases/latest/download/install.sh | CHANNEL=prerelease sh

# Specific version
curl -fsSL https://github.com/Sinotrade/Shioaji/releases/latest/download/install.sh | VERSION=v1.5.6 sh

The CHANNEL and VERSION environment variables are how you choose between the stable and pre-release tracks and how you pin an exact build, and the Windows equivalent is a PowerShell script using irm and iex with the same CHANNEL variable for the pre-release channel. The version numbers in the release list show both tracks running at once, with v1.7.9 and v1.7.8 on the main line and v1.5.8 as a separate line, which is why the channel and version variables exist rather than a single latest pointer.

Login, certificate, and what each one enables

The initialisation sequence is short and the order matters. You create the API object, log in with your key and secret, and then activate the certificate:

python
import shioaji as sj

api = sj.Shioaji()
accounts = api.login(api_key="YOUR_KEY", secret_key="YOUR_SECRET")
api.activate_ca(
    ca_path="/c/your/ca/path/Sinopac.pfx",
    ca_passwd="YOUR_CA_PASSWORD",
)

The README draws the line between the two stages explicitly: after logging in the API is ready for market data queries, and once the certificate is activated, order placement is enabled. That is a sensible separation for a trading API, since you can develop and backtest a strategy against live data without the ability to send an order, and it means the credential you hand to a research environment is not the same thing as the credential that can move money. The certificate is a pfx file with its own password, and the path in the example is the path on your machine.

Streaming data and order placement

Market data is subscribed per contract with a quote type, which is how the same contract can give you different streams:

python
api.subscribe(api.Contracts.Stocks["2330"], quote_type="tick")
api.subscribe(api.Contracts.Stocks["2330"], quote_type="bid_ask")
api.subscribe(api.Contracts.Futures["TXFC0"], quote_type="tick")

An order is defined and then placed alongside its contract, and the call returns a trade object representing the order's status:

python
contract = api.Contracts.Stocks["2890"]
order = sj.StockOrder(
    price=9.6,
    quantity=1,
    action=sj.Action.Buy,
    price_type=sj.StockPriceType.LMT,
    time_in_force=sj.TimeInForce.ROD,  # legacy name order_type= is still accepted
    order_lot=sj.StockOrderLot.Common,
    account=api.stock_account,
)
trade = api.place_order(contract, order)

The shape of that call is the part worth copying. The order carries its own price, quantity, action, price type, time in force, lot and account, and the comment on the time in force line notes that the legacy name order_type is still accepted, which is the sort of detail that tells you the API has been revised without breaking callers. The contracts are reached through api.Contracts, with a Stocks map and a Futures map, and the futures example uses a continuous index symbol.

The HTTP surface, the dashboard and the simulator

The non-Python path is not a thin wrapper. On the HTTP side the README points to a built-in OpenAPI interactive document, server-sent events for real-time streaming, and a visual dashboard that gives live monitoring of server status, SSE connections, CA certificates, accounts and API usage. The dashboard is the piece that turns an API into an operation you can watch, which matters when a strategy is running unattended and the difference between a working certificate and an expired one is otherwise invisible. There is also a trading simulator in the topic list, which is the usual way to develop against the API without sending real orders. On the Python side the README notes that the API behaves like other popular Python packages, importing and constructing an instance and then calling methods, which is a low-friction onboarding for a research team that has never traded programmatically.

AI coding agent support, and where Shioaji is the wrong choice

The newest thing in the project is agent integration, and the claim is that it is the first Taiwan trading API with AI coding agent skill support. The installs are plugin marketplace additions for Claude Code and Codex, and multi-platform installers through npx for skills.sh, skillkit and openskills, described as covering 18 or more agents, 32 or more agents, and universal respectively, with Cursor to come once the plugin is published through the Cursor marketplace or the publisher flow. Against a general market data vendor, the difference in approach is that this is a broker's own API with a simulator, a dashboard and certificate-based order placement rather than a data feed you attach to a separate execution system, which is convenient inside Taiwan and useless outside it. Three cases make it the wrong choice: a strategy for a market Sinopac does not serve, a team that wants a data feed without the ability to trade, and anyone who cannot hold a broker account, since the API key and the certificate are the entry requirements and the certificate is what gates order placement.

Editorial conclusion

Shioaji is a good fit for a developer building a Taiwan market strategy who wants one API that runs from a Python research environment and from a service written in Go or TypeScript, and for a team that wants to prototype against a simulator before trading real money. It is a poor fit if you are outside Taiwan or need another market, since the contracts, sessions and certificate flow are Sinopac's, and it is a poor fit for anyone who cannot hold a broker account, because an API key and a certificate are the entry requirements. Check three things before you start: that you can obtain an account and the certificate, since login alone gives market data while order placement needs the certificate activated, that you pin your version line with something like shioaji==1.7.*, since PyPI keeps only the latest two patch releases of each line, and that you read the CLI wheel caveat, because the CLI is absent from the free-threaded Python 3.14t wheels.

Frequently asked questions

What is Shioaji?

It is a trading API provided by Sinopac for accessing the Taiwan financial markets, described as a cross-language, cross-platform universal trading platform. It handles stocks, futures, options and combo orders through native Python bindings or through HTTP for JavaScript, Go, C, C#, Rust and Java clients.

How do I install the Shioaji Python package?

With uv, using uv add shioaji, or with pip using pip install shioaji. To pin a release line you would use something like uv add "shioaji==1.7.*", because PyPI keeps only the latest two patch releases of each line and releases with the same first two version parts never make incompatible changes.

What do I need before I can place orders with Shioaji?

An API key and secret to log in, and a certificate activated with activate_ca using the path to a Sinopac pfx file and its password. The README states that after logging in the API is ready for market data queries, and that order placement is enabled only once the certificate is activated.

Does Shioaji work outside Python?

Yes. The HTTP side is reachable from any HTTP-capable language, with JavaScript and TypeScript, Go, C and C++, C#, Rust and Java and Kotlin named. That side comes with a built-in OpenAPI interactive document, server-sent events for real-time streaming, and a dashboard for live monitoring of server status, SSE connections, certificates, accounts and API usage.

How do I install the Shioaji CLI?

With uv tool install shioaji, or uv tool install shioaji-cli to get only the CLI on any Python version. The CLI ships in the regular wheels, and the free-threaded Python 3.14t wheels do not include it, so the CLI should be installed with a regular Python.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. Sinotrade/Shioaji on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sinotrade-shioaji.svg)](https://hysenlabs.com/projects/sinotrade-shioaji)

Was this useful?