chundev
日期:2026-03-16 目的:為台積電期貨策略系統(TSM)建置自動下單模組,從訊號到執行全自動化
用 Python + Shioaji API 建了一個獨立的自動下單 worker,透過 TSM 的 HTTP API 讀取策略訊號,執行期貨下單,並同步發送 Telegram + Threads 通知。目前以模擬模式運行,每日 08:30 自動執行。
TSM (Node.js, Docker) tsm-executor (Python, Docker)
┌────────────────────────┐ ┌──────────────────────┐
│ 15:30 算訊號 │ │ 08:30 cron 觸發 │
│ GET /api/executor/ │◄────────│ 讀取訊號 │
│ signal │ Bearer │ Shioaji 下單(模擬) │
│ │ Token │ │
│ POST /api/executor/ │◄────────│ 回報執行結果 │
│ report │ │ │
│ → DB + Telegram │ └──────────────────────┘
│ → Threads │
└────────────────────────┘
↕
PostgreSQL
兩個獨立 repo,共用同一個 docker-compose.prod.yml。
.pfx)tsm-executor/
├── Dockerfile
├── requirements.txt # shioaji, python-dotenv, psycopg2-binary
├── .env # API Key、憑證路徑(不入版控)
├── cron/
│ └── executor-cron.sh # server crontab 用
└── src/
├── config.py # 環境變數
├── broker.py # Shioaji 登入、買進、賣出
└── executor.py # 主流程:讀訊號 → 下單 → 回報
| Endpoint | 方法 | 用途 |
|---|---|---|
/api/executor/signal |
GET | 回傳今日策略訊號(繞過 Free/Pro 限制) |
/api/executor/report |
POST | 接收執行結果 → 寫 DB + 發 Telegram + Threads |
兩個 endpoint 都用 Bearer Token 保護,外部無法存取。
model ExecutionOrder {
// 每筆下單紀錄(買進/賣出各一筆)
action String // "buy" | "sell"
contracts Int
signalPrice Float // 回測引擎的理論價
filledPrice Float? // 實際成交價
status String // "simulated" | "filled" | "failed"
mode String // "simulation" | "live"
}
model ExecutionPosition {
// 一筆完整交易(進場 → 出場)
status String // "open" | "closed"
entryDate String
entryPrice Float
exitDate String?
exitPrice Float?
returnRate Float? // 報酬率 %
mode String // "simulation" | "live"
}
executor 用獨立 image,透過 compose profile 隔離:
# docker-compose.prod.yml
services:
app:
image: tsm:latest # 676MB
executor:
image: tsm-executor:latest # 128MB
profiles: ["executor"] # 不隨 up -d 自動啟動
environment:
TSM_API_URL: http://app:3050/api/executor/signal
TSM_REPORT_URL: http://app:3050/api/executor/report
http://app:3050),不經外部docker compose run --rm# 每週一到週五 08:30(開盤前 15 分鐘)
30 8 * * 1-5 cd /home/deploy/tsm && \
docker compose -f docker-compose.prod.yml --env-file .env.production \
--profile executor run --rm executor python src/executor.py \
>> /home/deploy/tsm-executor/logs/cron.log 2>&1
| 項目 | 設定 |
|---|---|
| 商品 | CDF(台積電期貨)近月合約 CDFR1 |
| 進場 | 市價單(MKT) — 隔夜跳空限價單容易掛不到 |
| 出場 | 市價單(MKT) — 儘快平倉 |
| 委託類型 | ROD(當日有效) |
| 時機 | 08:30 掛單,08:45 開盤成交 |
executor 執行後會同時發送兩個通知:
Telegram:
[盤前執行] 2026-03-17(模擬)
P/C:158.9 | 期貨:1870
🟢 進場
買進 CDF 1 口 @ 1870
(模擬,未實際下單)
Threads: 同上內容,公開發佈。
透過 Threads 貼文可以驗證系統是否每天正確執行。
目前以模擬模式運行(SIMULATION=true),不實際下單。
切換實盤只需要改一個環境變數:
# server 上的 .env.production
EXECUTOR_SIMULATION=false
建議模擬跑至少 2-4 週,確認:
# 在 TSM 專案目錄下
make build-executor # 本地 build executor image
make push-executor # build + 傳送到 server
make deploy # 部署 TSM 主應用(不含 executor)
| 測試項目 | 結果 |
|---|---|
| Shioaji 登入 | ✅ |
| CDF 合約查詢(7 個合約) | ✅ |
| 模擬買進/賣出/查詢/取消 | ✅ 全部 PendingSubmit |
| TSM signal API(本地) | ✅ 回傳即時訊號 |
| TSM signal API(server) | ✅ Token 驗證正常 |
| executor dry run(本地) | ✅ 正確讀到持倉 |
| executor dry run(server) | ✅ Docker 內部網路正常 |
| crontab 排程 | ✅ 已設定 |
os._exit(0) 繞過,不影響功能)CDFR1 在結算日前後會自動切換,策略的 avoidSettlementDays: 2 可避免踩到restart: "no" + profiles: ["executor"],不會隨 docker compose up -d 自動啟動