Skip to main content
Glama
scorpio-su

sj-trading-mcp

by scorpio-su

sj-trading-mcp

永豐 Shioaji MCP Server,讓 Claude(或任何 MCP 客戶端)能直接操作台灣股票、期貨與選擇權交易,並查詢即時行情與帳務資料。
遵循 OOP + Clean Code(Uncle Bob) 原則,預設執行於 simulation=True 模擬環境。


專案結構

sj_trading-mcp/
├── config/
│   ├── credentials.json.example  ← 金鑰範本(JSON 格式)
│   ├── credentials.txt.example   ← 金鑰範本(key=value 格式)
│   ├── credentials.json          ← 實際金鑰(git ignored)
│   └── credentials.txt           ← 實際金鑰(git ignored)
├── src/
│   ├── core/
│   │   ├── credentials.py        ← 金鑰載入器(支援 .json / .txt 自動判斷)
│   │   └── api_client.py         ← Shioaji 連線封裝(支援 with 語法)
│   ├── market/
│   │   ├── stock_market.py       ← 股票行情:快照、K 線、Tick、資券、券源
│   │   ├── futures_market.py     ← 期貨行情:歷史 K 線(含連續合約)
│   │   └── market_info.py        ← 市場資訊:掃描器排行、處置股、注意股
│   ├── accounting/
│   │   ├── stock_account.py      ← 股票帳務:餘額、交易額度、交割資訊
│   │   ├── futures_account.py    ← 期貨帳務:保證金查詢
│   │   └── common_account.py     ← 跨帳戶:損益查詢、持倉明細
│   ├── trading/
│   │   ├── stock_trader.py       ← 股票交易:下單、改單、市價單、查持倉
│   │   ├── futures_trader.py     ← 期貨交易:開平倉、改單、查持倉
│   │   └── options_trader.py     ← 選擇權交易:下單、刪單、查持倉
│   ├── option_strategy/
│   │   ├── _types.py             ← 資料模型:Action / Right / InstrumentType / Leg / Strategy
│   │   ├── _pure_option.py       ← 純選擇權策略(45 種)
│   │   ├── _stock_legged.py      ← 含股票腿策略(6 種)
│   │   ├── _future_legged.py     ← 含期貨腿策略(7 種)
│   │   └── strategies.py         ← 策略總表 STRATEGIES + get_strategy()
│   └── grid_martingale_strategy/
│       ├── __init__.py           ← 對外 export 兩策略 + factories
│       ├── base/                 ← BaseStrategy、TradeJournal、RiskPolicy
│       ├── grid/                 ← GridStrategy、GridConfig、build_grid_strategy
│       ├── martingale/           ← MartingaleStrategy、MartingaleConfig、build_martingale_strategy
│       ├── adapters/             ← MarketAdapter + stock/futures 實作
│       ├── risk/                 ← GridRisk、MartingaleStockRisk、MartingaleFuturesRisk
│       ├── config/               ← 向後相容 re-export(grid/、martingale/ 為 canonical)
│       └── _types.py             ← 共用 enum / dataclass
├── tests/
│   ├── test_stock.py             ← 股票模擬測試
│   ├── test_futures.py           ← 期貨模擬測試
│   ├── test_market.py            ← 行情資料模擬測試
│   ├── test_accounting.py        ← 帳務查詢模擬測試
│   └── test_options.py           ← 選擇權模擬測試
├── .claude/
│   └── settings.json             ← Claude Code MCP 設定
├── server.py                     ← MCP Server 主程式
├── main.py                       ← 快速端對端測試(含 grid / martingale)
├── Dockerfile
├── pyproject.toml
└── requirements.txt

設定金鑰

複製範本後填入真實值:

# JSON 格式
cp config/credentials.json.example config/credentials.json

# 或 txt 格式
cp config/credentials.txt.example config/credentials.txt

僅行情 / 股票下單credentials.json,不需 CA):

{
  "api_key": "YOUR_API_KEY",
  "secret_key": "YOUR_SECRET_KEY"
}

期貨 / 選擇權下單須填寫 CA 憑證欄位(模擬與真實模式皆需):

{
  "api_key": "YOUR_API_KEY",
  "secret_key": "YOUR_SECRET_KEY",
  "ca_path": "config/ca/YOUR_CA.pfx",
  "ca_password": "YOUR_CA_PASSWORD",
  "person_id": "YOUR_PERSON_ID"
}

CA 欄位存在時,ApiClient 在連線後立即啟動憑證(無論模擬或真實模式)。
TAIFEX(期貨交易所)即使在模擬環境也需要帳戶層級的 CA 簽署才能接受委託。


Docker 啟動(推薦)

# 第一次 build
docker build -t sj-trading-mcp .

# 啟動(模擬模式)
docker run -d \
  --name sj-trading-mcp \
  -p 127.0.0.1:9090:9090 \
  -v ./config:/app/config:ro \
  -v ./logs:/app/logs \
  --restart unless-stopped \
  sj-trading-mcp

# 真實下單模式
docker run -d \
  --name sj-trading-mcp \
  -p 127.0.0.1:9090:9090 \
  -v ./config:/app/config:ro \
  -v ./logs:/app/logs \
  -e SJ_SIMULATION=false \
  --restart unless-stopped \
  sj-trading-mcp

停止 / 重啟:

docker stop sj-trading-mcp
docker start sj-trading-mcp

查 log:

docker logs -f sj-trading-mcp
# 或查 log 檔
cat logs/server.log

整合 Claude Code

.claude/settings.json 已預設配置,在此專案目錄下開啟 Claude Code 即自動載入。

CLI 加入(專案範圍):

claude mcp add sj-trading --transport http http://127.0.0.1:9090/mcp --scope project

MCP 工具清單

連線管理

工具

說明

connect_api(simulation)

連線 API(simulation=true 預設模擬,false 真實下單)

disconnect_api()

登出斷線

connection_status()

查詢連線狀態

股票交易

工具

說明

stock_buy(symbol, price, quantity)

整股限價買進(ROD)

stock_sell(symbol, price, quantity)

整股限價賣出(ROD)

stock_market_buy(symbol, quantity)

整股市價買進(MKT + IOC)

stock_market_sell(symbol, quantity)

整股市價賣出(MKT + IOC)

stock_buy_odd(symbol, price, quantity, intraday)

零股買進

stock_sell_odd(symbol, price, quantity, intraday)

零股賣出

stock_margin_buy(symbol, price, quantity)

融資買進

stock_margin_sell(symbol, price, quantity)

融資賣出/還券

stock_short_sell(symbol, price, quantity)

融券賣出

stock_short_cover(symbol, price, quantity)

融券回補

stock_cancel(order_id)

刪除委託單

stock_update_order(order_id, price, qty)

改價或減量(二選一)

stock_list_trades()

查詢所有委託紀錄

stock_positions()

查詢股票持倉

stock_contract_info(symbol)

查詢合約基本資訊

期貨交易

工具

說明

futures_open_long(symbol, price, quantity)

開多倉(Buy + OCType.New)

futures_open_short(symbol, price, quantity)

開空倉(Sell + OCType.New)

futures_close_long(symbol, price, quantity)

平多倉(Sell + OCType.Cover)

futures_close_short(symbol, price, quantity)

平空倉(Buy + OCType.Cover)

futures_cancel(order_id)

刪除委託單

futures_update_order(order_id, price, qty)

改價或減量

futures_positions()

查詢期貨持倉

futures_contract_info(symbol)

查詢合約基本資訊

選擇權交易

工具

說明

options_buy(symbol, price, quantity, octype)

買進選擇權(LMT + ROD)

options_sell(symbol, price, quantity, octype)

賣出選擇權(LMT + ROD)

options_cancel(order_id)

刪除委託單

options_positions()

查詢選擇權/期貨持倉

options_contract_info(symbol)

查詢合約資訊(到期月、履約價、Call/Put)

symbol 格式:TXO20260620200C(商品代碼 + YYYYMMDD + 履約價 + C/P)
octype"Auto"(預設)/ "NewPosition"(新倉)/ "Cover"(平倉)

選擇權策略(多腿組合)

工具

說明

strategy_list()

列出所有可用策略(純選擇權 45 種、含股票腿 6 種、含期貨腿 7 種,共 58 種)

strategy_info(strategy_id)

查詢策略腿部結構(方向、標的類型、Put/Call、履約價位、口數)

strategy_execute(strategy_id, leg_symbols, leg_prices, base_qty)

執行多腿策略,逐腿送出委託

使用流程:strategy_list()strategy_info() 確認腿部順序 → strategy_execute() 下單
leg_symbols / leg_prices 長度須與策略腿數一致;base_qty 為口數乘數(預設 1

網格策略(Grid)

工具

說明

grid_create(market_type, symbol, upper_price, lower_price, grid_count, grid_unit_qty, ...)

建立純網格策略,回傳 grid-N

grid_start(strategy_id)

啟動(idle → running)

grid_stop(strategy_id)

停止行情訂閱

grid_status(strategy_id)

查詢狀態(strategy_type=grid、格位數、triggered_levels)

grid_rebalance(strategy_id)

重新對齊格位

grid_destroy(strategy_id)

停止並移除

grid_list()

列出所有網格策略

使用流程grid_create(...)grid_start('grid-1')grid_status(...)grid_stop / grid_destroy
grid_create 不再包含馬丁參數;grid_mode"arithmetic" / "geometric"direction"LONG" / "SHORT"(僅期貨)

馬丁格爾策略(Martingale)

工具

說明

martingale_create(market_type, symbol, mart_multiplier, mart_trigger_pct, mart_max_times, mart_initial_qty, mart_take_profit_pct, ...)

建立純馬丁策略,回傳 mart-N

martingale_start(strategy_id)

啟動(idle → running)

martingale_stop(strategy_id)

停止行情訂閱

martingale_status(strategy_id)

查詢狀態(layer_count、avg_cost、frozen、liquidating)

martingale_destroy(strategy_id)

停止並移除

martingale_list()

列出所有馬丁策略

使用流程martingale_create(...)martingale_start('mart-1')martingale_status(...)martingale_stop / martingale_destroy
qty_mode"multiply" / "linear";策略 ID 前綴為 mart-(與網格的 grid- 分開管理)

網格與馬丁為完全獨立策略:grid/martingale/ 互不 import,可各自建立、各自運行。原 GridMartingaleStrategy / build_strategy 已移除。

行情資料

工具

說明

stock_snapshot(symbols)

即時快照(最多 500 檔,含現價 / 漲跌 / 量)

stock_kbars(symbol, start, end)

歷史 K 棒(1 分鐘),start/end 格式 YYYY-MM-DD

stock_ticks(symbol, date, query_type, ...)

歷史 Tick,query_type: "AllDay" / "RangeTime" / "LastCount"

stock_credit_enquiries(symbols)

個股融資融券餘額

stock_short_sources(symbols)

可借券來源與張數

futures_kbars(symbol, start, end)

期貨歷史 K 棒(支援連續合約 TXFR1/TXFR2

market_scanners(scanner_type, ascending, count)

市場排行掃描器

market_punish()

處置股清單

market_notice()

注意股清單

scanner_type 可用值:"ChangePercentRank" / "ChangePriceRank" / "DayRangeRank" / "VolumeRank" / "AmountRank"

帳務查詢

工具

說明

account_balance()

股票帳戶可用餘額

stock_trading_limits()

股票交易額度(含融資 / 融券額度)

list_settlements()

交割資訊(T / T+1 / T+2)

futures_margin()

期貨保證金(可用保證金、風險指標等)

list_profit_loss(account_type, begin_date, end_date)

已實現損益,按日期區間查詢

list_position_detail(account_type, detail_id)

持倉明細(含成本價、進場日)

account_type"stock""futopt"


核心模組說明

CredentialsLoadersrc/core/credentials.py

  • 單一職責:只負責讀取與驗證金鑰

  • frozen=True dataclass 保存,防止意外修改

  • 缺少欄位時拋出含明確說明的 KeyError

ApiClientsrc/core/api_client.py

  • 封裝 login / logout 流程

  • 支援 with 語法,確保 logout 必然執行

  • 未連線前訪問 .api 屬性拋出 RuntimeError

  • 所有模組共用同一 ApiClient 實例(避免超過 5 connections/person ID 上限)

  • 若 credentials 含 CA 欄位,則模擬與真實模式皆啟動憑證(期貨 / 選擇權下單需要)

Trading 模組(src/trading/

模組

類別

主要方法

stock_trader.py

StockTrader

buy / sell / market_buy / market_sell / buy_odd / sell_odd / margin_buy / short_sell / cancel / update_order / list_trades / list_positions

futures_trader.py

FuturesTrader

open_long / open_short / close_long / close_short / cancel / update_order / list_positions

options_trader.py

OptionsTrader

buy / sell / cancel / contract_info / list_positions

Market 模組(src/market/

模組

類別

主要方法

stock_market.py

StockMarket

stock_snapshot / stock_kbars / stock_ticks / credit_enquiries / short_stock_sources

futures_market.py

FuturesMarket

futures_kbars

market_info.py

MarketInfo

market_scanners / market_punish / market_notice

Accounting 模組(src/accounting/

模組

類別

主要方法

stock_account.py

StockAccount

account_balance / trading_limits / list_settlements

futures_account.py

FuturesAccount

futures_margin

common_account.py

CommonAccount

list_profit_loss / list_position_detail

OptionStrategy 模組(src/option_strategy/

純資料驅動的多腿策略定義層,不依賴 Shioaji API,可獨立測試。

類型

策略數量

範例

純選擇權(_pure_option.py

45 種

long_call / straddle / iron_condor / calendar_call_spread / double_diagonal …

含股票腿(_stock_legged.py

6 種

covered_call / protective_put / collar / cash_secured_put …

含期貨腿(_future_legged.py

7 種

long_synthetic_future / protective_futures_put / futures_collar …

  • Strategy — frozen dataclass,持有 strategy_idlegs: tuple[Leg, ...]

  • OptionLeg / StockLeg / FutureLeg — 各腿類型,描述 action(BUY/SELL)、qty、right、strike、expiry

  • get_strategy(strategy_id) — 依 ID 取得策略,找不到時拋出 KeyError

  • server.py 使用此模組實作 strategy_list / strategy_info / strategy_execute 三個 MCP 工具

策略模組(src/grid_martingale_strategy/

網格與馬丁已拆分為兩個獨立策略,共用 base/ 骨架(Template Method)與 adapters/ 基礎設施。
grid/martingale/ 互不 import,各自持有專屬 config 與 position book。

子模組

職責

base/

BaseStrategyTradeJournalRiskPolicyGridRiskPolicy / MartingaleRiskPolicy

grid/

GridStrategyGridConfigGridPositionBookbuild_grid_strategy()

martingale/

MartingaleStrategyMartingaleConfigLayerBookbuild_martingale_strategy()

adapters/

MarketAdapter + stock/futures 實作

risk/

GridRiskMartingaleStockRiskMartingaleFuturesRisk

對外 API(__init__.py):

符號

說明

GridStrategy / build_grid_strategy

純網格

MartingaleStrategy / build_martingale_strategy

純馬丁

GridConfig / MartingaleConfig

各自設定 dataclass

MarketType / Direction / GridMode / QtyMode / StrategyState

共用列舉

MartingaleConfig 第一個參數為 symbol(拆分後新增)。
舊路徑 config/grid_config.pyconfig/martingale_config.py 仍 re-export,canonical 位置分別在 grid/martingale/

from src.grid_martingale_strategy import (
    build_grid_strategy, build_martingale_strategy,
    GridConfig, MartingaleConfig,
    MarketType, Direction, GridMode, QtyMode,
)

grid_cfg = GridConfig("2330", 1000.0, 800.0, 10, GridMode.ARITHMETIC, grid_unit_qty=1)
grid = build_grid_strategy(MarketType.STOCK, client, grid_cfg)
grid.initialize(); grid.start()

mart_cfg = MartingaleConfig("2330", 2.0, -0.05, 3, 2, 0.03, QtyMode.MULTIPLY)
mart = build_martingale_strategy(MarketType.STOCK, client, mart_cfg)
mart.initialize(); mart.start()

執行測試

所有測試皆在 simulation=True 模擬模式下執行,不會觸發真實交易

uv run python tests/test_stock.py
uv run python tests/test_futures.py
uv run python tests/test_market.py
uv run python tests/test_accounting.py
uv run python tests/test_options.py

測試檔

必要條件

備註

test_stock.py

僅 api_key / secret_key

股票模擬完整測試

test_futures.py

CA 憑證(建議)

無 CA 或帳戶未在 TAIFEX 簽署時,下單步驟自動跳過並顯示警告

test_market.py

僅 api_key / secret_key

行情查詢不需 CA

test_accounting.py

僅 api_key / secret_key

帳務查詢不需 CA

test_options.py

僅 api_key / secret_key

合約與持倉查詢;自動尋找當前有效 TXO 合約

main.py 快速端對端測試(含 Grid / Martingale):

python main.py                  # 全部測試(stock + futures + options + grid + martingale)
python main.py stock            # 只測股票
python main.py futures          # 只測期貨
python main.py options          # 只測選擇權
python main.py grid             # 只測純網格(現股)
python main.py grid_futures     # 只測純網格(期貨)
python main.py martingale       # 只測純馬丁(現股)
python main.py martingale_futures  # 只測純馬丁(期貨)

環境變數

變數

預設

說明

SJ_SIMULATION

true

false 切換真實下單

MCP_HOST

0.0.0.0

server 監聽 host

MCP_PORT

9090

server 監聽 port

LOG_DIR

logs

log 檔目錄


Design Principles

  • SRP:每個 class 只負責一件事(交易 / 行情 / 帳務明確分層)

  • 依賴注入:所有模組接收 ApiClient,不直接建立連線

  • 共用連線_Session 管理單一 ApiClient 生命週期,防止超過連線數上限

  • 語意方法名open_long / close_short 優於 place_order(octype=...)

  • 不回傳 None:錯誤以例外表達(ValueError / RuntimeError

  • 非同步行情與帳務:市場資料與帳務工具使用 async + run_in_executor 避免卡頓


⚠️ 注意事項

  • 預設 SJ_SIMULATION=true,絕對不會動用真實帳戶。

  • 期貨 / 選擇權委託(含模擬模式)需在 credentials 填入 CA 欄位,且帳戶需已在 TAIFEX 完成 CA 簽署。

  • 切換真實模式前,請確認 CA 欄位(ca_pathca_passwordperson_id)正確填寫。

  • 真實下單操作不可逆,請在確認合約、價格、數量後再執行。

  • 行情查詢限速:50 req / 5s;帳務查詢限速:25 req / 5s。