| name | neoapi-python |
| version | 1.0.0-beta.32 |
| description | Fubon Neo (富邦新一代/富邦 API) Python SDK guidance focused on trading and market data workflows, including login, market data access, order placement, and locating the right docs/llms outputs. Use when prompts mention FubonNeo API or the Python SDK. |
NeoAPI Python
Overview
本 skill 教導 AI 編程代理使用 Fubon Neo Python SDK 進行台股證券交易與行情資料存取。適用 Python 3.8–3.13、SDK >= 2.x(避免 3.14)。預設 SDK ~2.2.8,除非使用者另外指定。
TL;DR — 三大工作流程:
- 登入 →
sdk.login(ID, PWD, cert, cert_pwd) 取得帳號清單
- 下單 → 建構
Order(...) → sdk.stock.place_order(acc, order)
- 行情 →
sdk.init_realtime() → sdk.marketdata.rest_client.stock.intraday.*
Shioaji migration routing
When the user asks to migrate or port existing Shioaji code, keep the tone practical and neutral: help them translate working code safely; do not frame the answer as a broker comparison. Load references/migration-shioaji.md first, then add the narrow reference below when needed.
| Migration task | Load / check |
|---|
| Login / CA / account selection | references/migration-shioaji.md + official login docs |
| Stock order placement | references/migration-shioaji.md + references/implementation-practices.md |
| Modify / cancel / status tracking | references/migration-shioaji.md + references/response-shapes.md |
| Quantity or lot-size confusion | references/migration-shioaji.md (Neo quantity is shares) |
| Test vs production behavior | references/test-environment.md |
| WebSocket / callback migration | references/migration-shioaji.md + references/examples-guidance.md |
常見錯誤(Common Mistakes)
| 錯誤 | 正確做法 |
|---|
pip install fubon-neo | SDK 不在 PyPI,需從官方頁面下載 .whl 安裝 |
在測試環境用 intraday.quote 判斷可下單價格 | 測試環境應用 sdk.stock.query_symbol_quote(acc, symbol) |
SDK >= 2.2.1 仍用 FubonSDK() 初始化 | 需用 FubonSDK(30, 2) (或含 url= 參數) |
預設憑證密碼卻傳 cert_pass="" | SDK >= 1.3.2 應省略第 4 個參數:sdk.login(id, pwd, cert_path);不要用空字串代替 |
| 下單後找不到已刪的單 | 已刪單仍在 get_order_results 中,status=30 |
登入後直接用 sdk.marketdata.rest_client | 需先呼叫 sdk.init_realtime() |
user_def 字串過長 | 建議 10 字元以內,過長會被截斷 |
| 在 Python 3.14 使用 SDK v2 | 官方目前支援 Python 3.8–3.13,不支援 3.14 |
| 數量填「張數」而非「股數」 | FubonNeo 數量一律為股數(1 張 = 1000 股) |
WebSocket on_message 直接取 message["price"] | 訊息是 envelope 結構,交易資料在 message["data"] 內,需先檢查 message["event"] == "data" |
用 data["price"] == "市價" 判斷 WebSocket 價格狀態 | 價格欄位是數值;值為 0 時應搭配同欄位的 isLimitUp* / isLimitDown* 旗標解碼,不能比對字串或臆測原始委託型別 |
Public Docs Access
Usage Cheat Sheet
Quickstart (Trading)
from fubon_neo.sdk import FubonSDK, Order, Mode
from fubon_neo.constant import BSAction, MarketType, PriceType, TimeInForce, OrderType
sdk = FubonSDK()
accounts = sdk.login("ID", "PWD", "C:/path/to/cert.pfx", "CertPWD")
acc = accounts.data[0]
order = Order(
buy_sell=BSAction.Buy,
symbol="2330",
quantity=1000,
market_type=MarketType.Common,
price_type=PriceType.Limit,
time_in_force=TimeInForce.ROD,
order_type=OrderType.Stock,
price="580"
)
res = sdk.stock.place_order(acc, order)
print(f"Order: {res.data.order_no}")
Certificate Password Login
accounts = sdk.login(user_id, login_password, cert_path, cert_password)
accounts = sdk.login(user_id, login_password, cert_path)
若程式從環境變數讀取自訂憑證密碼,請在缺值時直接報錯,不要用 os.getenv("CERT_PASSWORD", "") 靜默退回空字串。測試環境的憑證密碼則依官方測試包為 12345678。
官方依據:https://www.fbs.com.tw/TradeAPI/docs/trading/quickstart.txt。
Critical Constants
| Category | Class | Common Values |
|---|
| Action | BSAction | .Buy, .Sell |
| Price | PriceType | .Limit (限價), .Market (市價), .Reference (參考價) |
| Time | TimeInForce | .ROD (當日有效), .IOC (立即成交否則取消), .FOK (全部成交否則取消) |
| Market | MarketType | .Common (整股), .IntradayOdd (盤中零股), .Odd (盤後零股) |
| Order | OrderType | .Stock (現股), .MarginTrading (融資), .ShortSelling (融券) |
Validating Prices
Real-time quotes (intraday.quote) may differ from valid order prices (especially in Test Env).
- For Orders: Always check
sdk.stock.query_symbol_quote(acc, symbol).
- Use
limit_up_price / limit_down_price from this result for placing limit orders.
- This source reflects the order system's view of validity.
- For Display: Use
sdk.marketdata.rest_client.stock.intraday.quote(symbol).
Rate Limits (Summary)
- REST: 300 req/min (IP-based).
- WebSocket: 200 subscriptions per connection.
SDK 版本相容性(Version Compatibility)
| SDK Version | Python | Constructor | 備註 |
|---|
| >= 2.2.6 | 3.8–3.13 | FubonSDK(30, 2) | 下單錯誤拋出 FugleAPIError |
| 2.2.1–2.2.5 | 3.8–3.13 | FubonSDK(30, 2) | 錯誤在 response 物件中 |
| 2.0–2.2.0 | 3.8–3.13 | FubonSDK() | 無位置參數 |
| 1.3.1–1.x | 3.8–3.12 | FubonSDK() | 測試環境最低要求 |
測試環境一律加 url="wss://neoapitest.fbs.com.tw/TASP/XCPXWS" 參數。
工作流程決策樹(Workflow Decision Tree)
需求是什麼?
├── 交易(Trading)
│ ├── 下單 / 改單 / 刪單
│ │ ├── 測試環境?→ FubonSDK(30, 2, url=test_url) + query_symbol_quote 取價格
│ │ └── 正式環境?→ FubonSDK(30, 2) + intraday.ticker 取漲跌停
│ ├── 查詢帳務 → sdk.stock.get_order_results / get_inventories
│ └── 當沖(Day Trade)→ 見下方「當沖」章節
├── 行情(Market Data)
│ ├── 即時快照 → HTTP: intraday.quote(成交)/ intraday.ticker(參考價/漲跌停)
│ ├── 歷史資料 → HTTP: historical
│ └── 即時串流 → WebSocket: sdk.init_realtime() + subscribe
└── 環境確認
├── SDK 版本 → 見上方「版本相容性」
├── 安裝方式 → 官方 .whl(非 PyPI)
└── 文件查詢 → references/doc-index.md
Trading Workflow
- Start from
docs/trading/prepare and docs/trading/quickstart for setup.
- Use Python library references under
docs/trading/library/python/ for exact function names, parameters, and return types.
- Typical flow: login (password or API key) → place/modify/cancel order → query order/account info → logout.
- Always mention rate limits when relevant (
docs/trading/trade-rate-limit).
Market Data Workflow
- Decide on HTTP vs WebSocket:
- HTTP API for snapshots, intraday, historical.
- WebSocket API for real-time streams.
- Use
docs/market-data/http-api/getting-started and docs/market-data/websocket-api/getting-started.
- Mention connection setup and rate limits when relevant.
- To use
sdk.marketdata.rest_client, call sdk.init_realtime() after login.
- For limit-up/limit-down prices in market data, use
intraday.ticker (not intraday.quote).
- Raw WebSocket JSON uses camelCase flags such as
isLimitUpPrice and isLimitDownAsk; these booleans may be omitted when the condition is false, so read them with data.get(flag, False).
- WebSocket
price / bid / ask are numeric. If a price is 0, decode it together with the matching field-specific limit flags; never compare it to the string "市價", and do not claim the public quote reveals the original order type.
- Trading hours reference (Taiwan cash equities):
references/twse-trading-hours.md (Asia/Taipei)
Official field definitions: docs/market-data/websocket-api/market-data-channels/trades.txt and aggregates.txt.
def decode_ws_price_state(data: dict, field: str = "price") -> dict:
flag_names = {
"price": ("isLimitUpPrice", "isLimitDownPrice"),
"bid": ("isLimitUpBid", "isLimitDownBid"),
"ask": ("isLimitUpAsk", "isLimitDownAsk"),
}
if field not in flag_names:
raise ValueError(f"Unsupported WebSocket price field: {field}")
up_flag, down_flag = flag_names[field]
value = data.get(field)
if value is not None and (
not isinstance(value, (int, float)) or isinstance(value, bool)
):
raise TypeError(f"WebSocket {field} must be numeric")
is_limit_up = bool(data.get(up_flag, False))
is_limit_down = bool(data.get(down_flag, False))
return {
"value": value,
"is_zero_encoded": value == 0,
"is_limit_up": is_limit_up,
"is_limit_down": is_limit_down,
"has_limit_marker": is_limit_up or is_limit_down,
}
可直接重用並測試的完整版本在 references/guardrail_patterns.py。
當沖(Day Trading)
台股當沖分為:
- 先買後賣(現股當沖-買):先以
BSAction.Buy 下單,同日再以 BSAction.Sell 賣出。使用 OrderType.Stock。
- 先賣後買(現股當沖-賣/融券當沖):先以融券賣出,同日再買回。使用
OrderType.ShortSelling。
關鍵判斷
- 使用
intraday.ticker 回傳的 canDayTrade / canBuyDayTrade 欄位確認標的可否當沖(行情端的快速旗標)。
- 若你要更精確地判斷「先買後賣」vs「先賣後買」能不能做,建議查交易端的 status bitmask:
- 來源常見於:
sdk.stock.query_symbol_quote(acc, symbol) 回傳的 data.status
sdk.stock.daytrade_and_stock_info(acc, symbol) 回傳的 data.status(有些 wrapper 會叫 disposition_status)
- bitmask 定義(加總):
1:平盤下可融券賣出
2:平盤下可借券賣出
4:可先買後賣當沖(buy-first daytrade)
8:可先賣後買當沖(sell-first daytrade / daytrade short)
- 判斷請用 位元運算,不要用
>=:
def decode_daytrade_status(status: int) -> dict[str, bool]:
return {
"can_short_sell_below_flat": bool(status & 1),
"can_borrow_sell_below_flat": bool(status & 2),
"can_daytrade_buy_first": bool(status & 4),
"can_daytrade_sell_first": bool(status & 8),
}
- 部位平倉(沖銷):在收盤前以反向委託等量股數沖銷。
條件單當沖
SDK >= 2.2.4 支援條件單當沖(搜尋 llms-full.txt 中 ConditionDayTrade 或「當沖條件單」),可設定停損停利自動回補。
參考實作
期貨 / 選擇權(Futures & Options)
本 skill 目前以**證券(Stock)**交易與行情為主要範圍。SDK 支援期貨/選擇權帳號(account_type == "futopt"),但本 skill 尚未涵蓋對應的下單/行情 API。期貨條件單說明可搜尋 llms-full.txt 中「期貨條件單」。歡迎社群補充期貨/選擇權工作流程。
Examples
- Use
references/examples-guidance.md to map SDK calls to docs and avoid common modification pitfalls.
Testing / Sandbox
-
Official test bundle: https://www.fbs.com.tw/TradeAPI_SDK/sample_code/test_environment.zip
-
Use SDK v1.3.1+ and the test URL wss://neoapitest.fbs.com.tw/TASP/XCPXWS.
-
SDK v2.2.0 and earlier: FubonSDK(url=...)
-
SDK v2.2.1 and later: FubonSDK(30, 2, url=...) (30/2 are reference values).
-
Test credentials: ID from certificate; login password and cert password are 12345678.
-
See references/test-environment.md for operational notes (trading hours, shared account caveats).
-
Python SDK is downloaded from the official site (not PyPI); install the wheel locally.
-
Skill validation checklist: references/skill-tests.md.
-
Local integrated runner (maintainer-only; may be absent in some distributed skill copies): .test/test_runner.py
- If present, it can run:
--suite smoke: basic login + market/trade sanity checks
--suite complex: multi-symbol marketdata + dual-order lifecycle + callback coverage
--suite all: full coverage (includes complex checks)
- If it is missing, use the minimal smoke snippet below (login → logout; no orders).
Minimal smoke (test env, no orders):
from fubon_neo.sdk import FubonSDK
import os
URL = os.getenv("NEOAPI_TEST_URL", "wss://neoapitest.fbs.com.tw/TASP/XCPXWS")
sdk = FubonSDK(30, 2, url=URL)
accounts = sdk.login(
os.getenv("NEOAPI_TEST_ID"),
os.getenv("NEOAPI_TEST_PASSWORD"),
os.getenv("NEOAPI_TEST_CERT_PATH"),
os.getenv("NEOAPI_TEST_CERT_PASSWORD"),
)
print("login_ok=", bool(getattr(accounts, "is_success", True)))
sdk.logout()
- For limit-down/limit-up in test env, prefer
sdk.stock.query_symbol_quote (test environment data). intraday.quote uses market data (prod) and may differ.
SDK Install (Quick Note)
- Python SDK is not on PyPI. Download the wheel from the official page and install locally.
- SDK >= v2 works on Python 3.8–3.13 (avoid 3.14 for now).
即時成交回報 + Safe-net Readback
For live or latency-sensitive trading systems, treat filled callbacks as the primary fill source and get_order_results as a periodic reconciliation safe-net.
- Register callbacks before login/re-login when possible:
sdk.set_on_order(on_order) for order acknowledgements (OrderResult)
sdk.set_on_order_changed(on_order_changed) for modify/cancel reports (OrderResult)
sdk.set_on_filled(on_filled) for execution fills (FilledData)
sdk.set_on_event(on_event) for connection/re-login events
- Compute entry/exit average from execution data, not from submitted order price:
- preferred:
FilledData.filled_avg_price
- otherwise aggregate
filled_price * filled_qty across fills
- reconciliation fallback:
OrderResult.filled_money / filled_qty from sdk.stock.get_order_results(acc)
- Never use submitted limit price (
price, after_price, limit-up/down) as P/L entry price fallback. If fill price is missing, mark the position as unresolved and reconcile.
- Run
get_order_results periodically (for example every ~30 seconds) to detect missed callbacks and reconcile filled_qty, filled_money, and status.
- Reconcile records by
order_no + seq_no when available; include filled_no for idempotent fill dedupe.
- Record a
fill_source in receipts/state, such as active_filled_callback or order_results_readback, so operators can tell whether the low-latency path or the safe-net supplied the fill.
Implementation Patterns
For production-tested patterns, see references/implementation-practices.md. Key topics:
- SDK Manager: Connection lifecycle, auto-reconnect, graceful termination
- WebSocket: Multi-connection load balancing (200 symbols/connection limit)
- Async Patterns: ThreadPoolExecutor for blocking calls, per-symbol locking
- Error Handling: FugleAPIError compatibility for old/new SDK versions
- Order Placement: Order creation, placement, and fill handling
- Strategy Patterns: Tick-to-decision pipeline, stop loss, position sizing
- Error & Status Codes: Order status codes, HTTP errors, common rejection reasons
References
- Doc index:
references/doc-index.md
- Implementation practices:
references/implementation-practices.md
- Response shapes:
references/response-shapes.md
- Source docs (maintainers):
docs/ and i18n/en/docusaurus-plugin-content-docs/current
When code or docs need updating, mirror changes in the English localization if the content is user-facing.