Trading Agent — 系統架構圖
台股 TAIFEX 期貨自動化交易系統 · 三層策略架構 · 七層執行鏈
§ 1 · 七層執行鏈(launchd → external 世界)
從作業系統觸發到實際送單的垂直堆疊。每天靠 launchd 排程觸發,不需人工介入。
Layer 1 · 作業系統觸發
launchd(macOS 系統排程器)
com.hiram.trading-plan M
07:00 / 08:45 / 09:00 TPE 觸發 → 產 v1/v2/v3 morning plan
com.hiram.trading-midsession M
09:30 起每 15min 執行 → arbitration 決定 HOLD/TIGHTEN/FLAT/REVERSE
com.hiram.trading-intraday-day M
13:45 收盤後 intraday check
com.hiram.trading-evening E
20:00 / 22:30 TPE 觸發 → 產 evening plan + 夜盤 arbitration
com.hiram.trading-review R
14:00 TPE 一次 → 全日 review 寫 trade-reviews/<date>.json
⚠ launchd 沙盒不能讀 iCloud → trading-bridge 已遷出至 /Users/zosia/dev/trading-bridge/;trading-shared(資料)留在 iCloud 正確。
↓
Layer 2 · Wrapper 包裝腳本
~/start-trading-*.sh(薄 exec wrapper — 存在理由:launchd 只能 exec 非-iCloud 路徑)
一對一對應 Layer 3 業務腳本;bridge / agent / watchdog 三個是常駐 daemon 的啟動器。
start-trading-morning-plan.sh
exec → bridge morning-plan.sh(07:00 / 08:45 / 09:00 三版)
start-trading-midsession.sh
exec → bridge mid-session-replan.sh(日盤 15min)
start-trading-intraday-check.sh
exec → bridge intraday-check.sh(日盤 + 夜盤都用)
start-trading-review-day.sh
exec → bridge review-day.sh(13:45 日盤收盤)
start-trading-evening-plan.sh
exec → bridge evening-plan.sh(夜盤開盤前 SXF/TGF/BRF)
start-trading-evening-midsession.sh
exec → bridge evening-midsession.sh(夜盤 22:15–03:45 每 30min)
start-trading-bridge.sh
exec → node bridge daemon(MCP server,常駐)
start-trading-agent.sh
exec → python trading-agent state-machine(poll 30s,常駐)
start-trading-watchdog.sh
exec → bridge watchdog.sh(健康檢查,每 5min)
↓
Layer 3 · Bridge 業務腳本
/Users/zosia/dev/trading-bridge/scripts/
morning-plan.sh
v1/v2/v3 自動判斷、ensure_quote_server、呼叫 claude -p、split narrative/JSON、archive
mid-session-replan.sh
日盤 15min cadence、讀 current plan、arbitration prompt、寫 trade-arbitration/<time>.json
intraday-check.sh
日盤 + 夜盤輕量健檢(持倉 vs 當前 plan 一致性、breaker 狀態)
review-day.sh
13:45 日盤收盤後:trade-events 聚合、Obsidian daily note、Telegram 摘要
evening-plan.sh
夜盤開盤前 SXF / TGF / BRF 的 plan,prompt 走 evening 版本
evening-midsession.sh
夜盤 22:15–03:45 每 30min arbitration;prompt 用 mid-session-arbitration-evening.md
watchdog.sh
每 5min 健康檢查:bridge / agent daemon alive?quote-server 是否回應?
lib/ensure-quote-server.sh
開啟 trading-agent quote-server(Shioaji live quote,無 15min delay)
lib/split-narrative-plan.py
把 Claude 輸出拆成 narrative.md + plan.json 雙檔
↓
Layer 4 · Claude + MCP(智能層)
claude -p with allowed MCPs
mcp__agent-studio active
taifex_quote · Shioaji live quote
polymarket_macro · Fed/利率/衰退 odds
macro_calendar · high-impact events
portfolio_snapshot · 跨資產持倉
recent_briefs / read_session · 昨日 brief
mcp__tradingview active
chart_get_state · data_get_ohlcv · data_get_study_values · chart_manage_indicator · quote_get(15min delayed)
Pine 系列:pine_check/compile/new · alert_create/list
↓
Layer 5 · trading-shared(資料 + 規範 SSOT)
iCloud · 資料與配置的唯一真相源
📁 配置(Prompt + 策略架構)
prompts/ updated
morning-plan.md(含 Step -1 讀 DOCTRINE/symbols)· mid-session-arbitration.md(Vol Regime 分類)· evening-plan.md · review-day.md
strategies/ 三層架構
DOCTRINE.md(憲法)
trend_day_breakout · range_bound_fade · event_driven_bias · defensive_flat
SCHEMA.md · filter.py · stats.py · preprocess_or_baselines.py
symbols/ new
標的性格檔(instrument-specific profile)
TXF · SXF · BRF · TGF(YAML)
profiles/ new
每日 OR baseline 計算結果
<code>-baselines.json(preprocess 寫入)
📁 資料(Plan / Trade Log / Review)
trade-plans/ M
<date>.json + .md(morning 最新版)· archive/<date>/vN-HHMM.json(v1/v2/v3 保全演進)
trade-plans-evening/ E
夜盤 plan(與 morning 同結構,分開資料夾)
trade-arbitration/ live
mid-session 每 15min 一次 JSON,action = HOLD/TIGHTEN/FLAT/REVERSE
trade-logs/ live
trade-log-<date>.md(人讀)
trade-events-<date>.jsonl(機讀;stats.py 吃這個)
trade-reviews/ daily
<date>.json — review-day 輸出;lessons[] 陣列是朝 LESSONS.md 提升的候選
external-trades/ planned · Phase 2
朋友對帳單 + 回測資料 · <source>/{SOURCE.md, raw/, parsed/*.jsonl, notes/}
LESSONS.md
人工提升的 rule ledger — review → 觀察 pattern → 寫入 prompt 的 bridge
📁 狀態(Runtime State · 機器可改)
state/circuit-breaker.json live
cumulative_pnl_twd · tripped · tripped_at — daemon 每筆 event 後 atomic write
state/risk-override.json new · slider
daily_loss_pct · max_total_exposure_pct · total_capital_twd · per_trade_risk_pct
Studio slider PUT /api/trading/risk → 寫本檔;daemon cap_provider / preflight risk_provider 每次呼叫再讀(不快取,不重啟)
state/tradeable-status.json new
snapshot: per-symbol {enabled, signing_ok, margin_available, margin_required, state}
signing: 快取 per-symbol 7 天 probe 結果
dashboard 直接 read-only 讀這份,不打 HTTP
state/agent-runtime.json
state machine 位置、last tick、heartbeat — watchdog 檢查新鮮度
📁 配置(.env + symbols.yml)
.env pct-based
TOTAL_CAPITAL_TWD=200000
DAILY_LOSS_PCT=3.0 · PER_TRADE_RISK_PCT=1.5 · MAX_TOTAL_EXPOSURE_PCT=35
所有 NT$ cap 從百分比算出,資金變化只改 capital 一處
config/symbols.yml SSOT
per-symbol {enabled, margin_twd, note}
TXF 185k · MXF 46k · SXF 48k · TMF 4.6k · TGF · BRF
Studio toggle 寫回本檔 + patch cache;preflight gate 1 讀本檔
↓
Layer 6 · Daemon(Python, state machine)
trading-agent · 持倉 + 風控 + 送單
state_machine.py
讀 plan → 狀態機執行:AWAIT_ENTRY / OPEN / CLOSED;entry_filled / sl_hit / tp_hit 四大 event 寫 JSONL
plan.py strategy_used
Pydantic 讀 plan JSON;AssetPlan.strategy_used 貫穿到 trade-events
risk/circuit_breaker.py MUST dynamic cap
累積 PnL 觸 cap → 當日剩餘全部 no-entry;cap_provider lambda 每 tick 讀 risk-override.json,slider UI 調整立即生效,不需重啟
risk/risk_override.py new
RiskSnapshot dataclass;.env defaults(pct-based)+ runtime JSON override 兩層合併;atomic write (tmp+rename)
exchanges/preflight.py new 4 gates
① enabled(symbols.yml)
② signing(LMT 00 probe,7 天快取)
③ margin(available ≥ qty × margin_twd)
④ total exposure(used + new ≤ capital × max_total_exposure_pct)
can_trade(symbol, qty) → 第一個失敗 reason 回傳
notifier/events.py new
EventLogger — 機讀 JSONL sink,keyed by local date
notifier/dispatcher.py
NotifierBundle:telegram + obsidian markdown + events JSONL 三 fan-out
exchanges/shioaji_client.py
永豐 Shioaji adapter;simulation=True 為沙箱;preprocess_or_baselines 也 lazy import 它
↓
Layer 7 · External 世界
真實市場 · 券商 · 通知
永豐 Shioaji API
期貨送單(TXF/MXF/TMF/SXF/TGF/BRF)· kbars 歷史資料源
TradingView
圖表結構 + 指標;MCP 即時 OHLCV
Telegram
即時通知(fill / SL / TP / breaker)
Obsidian vault
trade-logs/*.md 直接供 Obsidian 瀏覽(Brain + Library 雙 vault)
§ 2 · 三層策略架構(憲法 → 法律 → 地方規則)
本次 v2 的核心升級:從散文策略 + 硬編碼 prompt,演化為可組合、可驗證、可追溯的三層架構。
Tier 1 · DOCTRINE(憲法)· 全系統共用
strategies/DOCTRINE.md
§ 1 MUST 不可違
• 硬 SL 必填(invalidation_price)
• 不加碼失敗單
• Circuit Breaker 神聖
• 事件黑名單:FOMC/NFP/CPI/EIA/OPEC 前 15min~後 30min
• 單日 SL ≥ 2 次 per symbol 停機
§ 2 SHOULD 可覆寫
• R:R 底線 ≥ 3:1
• size_pct ≤ 2.0%
• TP 分批預設 50/50
• morning ≤ 3 筆 · evening ≤ 4 筆
Override 需同檔寫 override_reason
§ 3 MAY 建議
• Vol Regime 四級公式(下詳)
• 第 2 根 K 方向判讀
• 「30 點換 400 點」R:R 放大哲學
• 標的 × 策略適配指南
§ 4 繼承規則
錢走 min(size/leverage 三層取小)
時間走 max(event_gate_hours / rr_min 三層取大)
最保守者勝
↓
Tier 2 · Symbol Profile(地方規則)· 標的性格檔
symbols/*.yml
| 代號 |
標的 |
主要 session |
性格 |
關鍵事件 |
preferred strategies |
size cap |
TXF |
台指期 |
morning 08:45–13:45 |
中性|trend/range 都吃 |
TSMC 財報 · 央行 · 夜盤跳空 |
trend_day_breakout · range_bound_fade |
2.0% |
SXF |
美股 S&P 期 |
evening 22:30–05:00 |
IB/OR 研究校準標的 |
FOMC · NFP · CPI · Mag7 earnings |
trend_day_breakout · event_driven_bias |
1.8% |
BRF |
布蘭特原油 |
evening 15:00–05:00 |
爆裂趨勢型|mean-reversion 會被海扁 |
EIA 週三 · OPEC · 中東地緣 |
trend_day_breakout · event_driven_bias avoid range_bound_fade |
1.5% |
TGF |
黃金期 |
evening 21:00–04:45 |
宏觀驅動 · 看 DXY / real yields |
FOMC · CPI · DXY 破位 |
trend_day_breakout · event_driven_bias |
1.5% |
↓
Tier 3 · Strategy(法律)· 何時觸發
strategies/<name>.md
| 策略 |
狀態 |
day_types |
rr_min |
activation_gate |
overridden_by / overrides |
trend_day_breakout |
active |
trend_day_up/down · breakout_day · gap_and_go |
2.0 |
— |
overridden_by: event_driven_bias |
range_bound_fade |
reference-only |
range_day · failed_breakout_day · reversal_day · gap_and_fill |
2.5 |
live_trades ≥ 3 backtest_hit_rate ≥ 0.50 median_rr ≥ 2.5 manual_review: true |
overridden_by: event_driven_bias |
event_driven_bias |
active |
(requires_event: true) |
2.0 (override) |
— |
overrides: trend_day_breakout, range_bound_fade |
defensive_flat |
active |
tight_consolidation · inside_day · unclear |
— |
— |
is_fallback: true(survivors=[] 時自動選) |
§ 3 · Vol Regime 判讀公式(DOCTRINE § 3.1)
每個 symbol 的 first_bar_tpe 那根 15min K 線的 range vs 20 日 rolling 基準,四級分類。業界 IB 研究:窄 OR → trend day 機率高(蓄能);寬 OR → range day 機率高(已動完)。第二根 K 收在 OR 外 ≈ 70–75% 當日續勢。
OR_range = today's bar1 (high - low)
baseline = profiles/<symbol>-baselines.json.or_baseline_points
ratio = OR_range / baseline
LOW_VOL : ratio < 0.7 → 蓄能,trend day 機率高
NORMAL : 0.7 ≤ ratio ≤ 1.3 → 無定論,等第 2–3 根
HIGH_VOL : 1.3 < ratio ≤ 2.0 → 寬 IB,range day 機率高
EXTREME : ratio > 2.0 → 疑似事件,size × 0.5 或空手
方向判讀(第 2 根 K 起):
bar2.close > OR.high → 多方突破(IB 研究 ~70% 當日續勢)
bar2.close < OR.low → 空方突破
bar2.close inside OR → range bias,等破
資料源 · morning 標的
Shioaji kbars API → preprocess_or_baselines.py 於 08:30 跑過 → 寫 profiles/TXF-baselines.json
(目前 stub,Shioaji live 呼叫待測)
資料源 · evening 標的
deferred:SXF/BRF/TGF baseline 由 Claude 在 mid-session replan 時用 TradingView MCP data_get_ohlcv 即時算
§ 4 · 資料流(plan → daemon → stats → review)
1
Claude 產 plan(07:00 / 08:45 / 09:00 morning;20:00 / 22:30 evening)
Read DOCTRINE + symbols/*.yml + profiles/*-baselines.json + strategies/*.md → 寫 narrative.md + plan.json(含 assets.<SYM>.strategy_used)
2
Daemon 讀 plan → Pydantic 校驗 → state machine 運作
invalidation_price 缺 → 拒絕送單(DOCTRINE § 1.1 MUST)
3
執行事件:entry_filled / sl_hit / tp_hit / breaker_tripped
→ NotifierBundle 三路 fan-out:Telegram(即時)+ trade-log-<date>.md(Obsidian 人讀)+ trade-events-<date>.jsonl(機讀,含 strategy_used)
4
Mid-session arbitration(每 15min)
讀 bar1 → 計算 Vol Regime → 決定 HOLD / TIGHTEN / FLAT / REVERSE → 寫 trade-arbitration/<time>.json
5
Review-day(14:00 TPE)
讀當日所有 event + arbitration + trade-log → 寫 trade-reviews/<date>.json(含 lessons[])
6
stats.py 聚合(手動 / Phase 3 自動)
讀 trade-events-*.jsonl → group by strategy_used → trade count / win rate / median R / cum PnL → 供 review-day 引用 + dashboard 顯示
7
LESSONS.md 人工提升
每週 Hiram 讀 reviews → 相同 pattern ≥ 2–3 次 → 寫進 LESSONS.md → 有把握時提升到 prompts/*.md 內嵌
§ 5 · Agent Studio 儀表板(viewer + controller)
Docker 容器(agent-studio, port 3210)— 掛載 trading-shared 為 rw volume,只讀資料 + 寫 risk-override/symbols.yml,沒有送單權限。單一來源:trading-shared 檔案系統。
Layer 8 · Studio Dashboard(cross-cutting · read/override only)
server/routes/trading.js · 所有端點 stdlib JS,不 shell-out 到 Python
📡 HTTP 端點
GET /api/trading/snapshot
plan(morning + evening)+ plan_versions(v1/v2/v3 archive)+ mid_session_versions + runtime + breaker + recent_events
GET /api/trading/tradeable new
per-symbol {enabled, signing_ok, margin_*, state}——讀 tradeable-status.json 快取(無 shioaji 依賴)
POST /api/trading/tradeable/toggle new
flip enabled in symbols.yml + patch cache(state=disabled/needs_preflight/ok 即時重算)
GET /api/trading/risk new
snapshot: capital · daily_loss_pct · cap_twd · today_loss · utilization_pct · remaining · tripped · source(env|override)
PUT /api/trading/risk slider
body: {daily_loss_pct, max_total_exposure_pct, total_capital_twd, per_trade_risk_pct} — validate 範圍、寫 risk-override.json(atomic)
GET /api/trading/strategies stats_30d
strategies[] 含 frontmatter(status/sessions/rr_min/...)
+ stats_30d(trades / win_rate / median_rr / cum_pnl)
stats.py JS 移植版,讀 trade-events-*.jsonl 30 天窗
🖥️ UI 組件(src/components/trading/)
TradingDashboard.jsx
Header(日期 + heartbeat + cum PnL)· 以下 tile 垂直堆疊
RiskControlPanel slider
可拖曳條 0.5–10% step 0.5,debounced PUT
顏色帶:<5% 綠 · 5–8% 橙 · >8% 紅
顯示:cap NT$ · today_loss · utilization bar · tripped 警示
TradeableTile new
per-symbol row:toggle switch + state badge + margin required/available;toggle 立即反映(patch cache)
PlanTimeline + MidSessionTimeline
morning v1/v2/v3 + evening + arbitration 時序;可逐版 diff
StrategiesLibraryTile stats
strategies/*.md 卡片式呈現;每卡附 30 天 trades/win_rate/median_rr/cum_pnl mini-stats
🔑 Studio 是 viewer 不是 executor。領域邏輯(preflight / circuit breaker / 送單)全留在 trading-agent。Studio 只改 risk-override.json 和 symbols.yml(intent layer),實際執行照例走 daemon 的 4 gates。
§ 6 · 外部資料接入(Phase 2 · ready to start)
解鎖 reference-only 策略的 activation_gate — 朋友對帳單、未來回測結果、模擬盤資料,統一透過此 pipeline 進入系統。
Planned Pipeline
1
raw drop →
external-trades/<source>/raw/<date>.pdf|png|txt
Hiram 丟對帳單原檔進去(無需預處理)
2
claude -p ingest-external-trades.md --source friend-jackson --date 2026-04-19
Claude OCR/解析 → 寫 parsed/<date>.jsonl(schema 對齊 trade-events + source 欄位)+ notes/<date>.md(人讀摘要)
3
更新 tracking:range_bound_fade.md 的
tracking.live_trades counter 自動 +N
同 Claude 執行;每批 ingest 完一次
4
validate_activation.py(新 script)
讀所有 reference-only 策略的 activation_gate → 對每條規則跑 check(live_trades count / hit_rate / median_rr / backtest / manual review)→ 印 PASS/FAIL → --promote flag 全 pass 時建議升 active,需人工 confirm
5
stats.py --include-external
預設 off 避免混吃;Phase 2.5 之後才把外部績效納入 dashboard 分組顯示
💡 Phase 2.1–2.3 純 infra 可先做(不需朋友 log 實際到位);Phase 2.4 需等朋友 ≥ 1 週對帳單外部依賴。
§ 7 · 一日時刻表(TPE)
07:00
morning-plan v1 · 1H/4H/1D 結構讀|trade-plans/<date>.json
08:30
preprocess_or_baselines(Phase 1+)· 更新 profiles/*-baselines.json
08:45
morning-plan v2 · 一般盤開盤、15m/30m 重新讀|OR 第一根形成中
09:00
morning-plan v3 · OR 收盤、分類 Vol Regime|LOW/NORMAL/HIGH/EXTREME
09:30–13:45
mid-session arbitration · 每 15min · HOLD/TIGHTEN/FLAT/REVERSE
13:45
一般盤收 · intraday-check 寫 summary
14:00
review-day · 寫 trade-reviews/<date>.json;lessons[] 是候選
15:00
夜盤開(BRF 為主場)
20:00
evening-plan v1 · 夜盤結構讀
21:00
TGF 黃金開
22:30
evening-plan v2 · SXF 美股 RTH 開盤|OR 第一根形成中
22:45
SXF OR 分類 · Vol Regime 寫入 arbitration
23:00–05:00
evening arbitration · 每 15min
05:00
夜盤收
§ 8 · Phase Roadmap
✅
PHASE 0
Markdown Library
4 策略 .md + README。純文件、零 code 改動。
✅
PHASE 1
機械化內層
SCHEMA + filter.py + stats.py + strategy_used 貫穿 + DOCTRINE + symbols/ + preprocess + prompt 串接。
🟡
PHASE 2 · ready
外部證據接入
純 infra 可立刻做(2.1–2.3)——external-trades/ dir shape · ingest-external-trades.md prompt · validate_activation.py · stats.py --include-external。
2.4 等朋友對帳單(外部依賴),但可用合成資料先測。
不是 blocker,就是還沒動工。
🔵
PHASE 3 · partial
回饋 loop 自動化
✅ Dashboard strategy_stats(/api/trading/strategies 附 stats_30d)
✅ review-day 自動建議 promote/keep/demote/retire(已入 prompt)
⏳ 自動改寫 strategies/*.md frontmatter status 欄位的 orchestrator 尚未做
⚪
PHASE 4
回測模組
Backtest engine 讀歷史 kbars 模擬策略;解 Gate 2 requires_backtest_hit_rate。需要獨立 kbars store + sim runner,最大投入。
§ 9 · 不變量(Invariants)
- 硬 SL 必填 — plan.py 拒絕缺 invalidation_price 的資產;daemon 不送單。
- Circuit Breaker 神聖 — 觸 NT$ cap 的當日所有 symbols 停止新 entry,既有倉照 SL/TP 執行。
- 不加碼失敗單 — 同 symbol 未出清前禁止新 entry(state machine 倉位鎖)。
- 事件黑名單 — FOMC/NFP/CPI/EIA/OPEC 前 15min 至後 30min 強制 flat;symbol 檔可加長不可縮短。
- 最保守者勝 — DOCTRINE ∩ Symbol ∩ Strategy 疊加時,錢走 min、時間走 max。
- Override 留痕 — 覆寫任何 SHOULD 預設值需寫 override_reason;filter.py --validate 檢查。
- Reference-only 策略不執行 — filter.py 只收 status: active;reference-only 需通過 activation_gate 人工升格。
- strategy_used 必填(非 flat bias 時)— 寫入 plan JSON + 流進 trade-events JSONL,供 stats.py 聚合。
- trading-bridge 不在 iCloud — launchd 沙盒限制;資料(trading-shared)留 iCloud 正確。
- 內外績效分家 — daemon trade-events 與 external-trades JSONL schema 同但 source 欄位區分;stats.py 預設不混吃。
- 所有風控值走百分比 — NT$ cap 從 TOTAL_CAPITAL_TWD × *_PCT 即算,資金變化改 capital 一處即可;禁止硬編碼 NT$ 常數(v1 CIRCUIT_BREAKER_TWD=6000 已遷移)。
- Slider 立即生效 — daemon cap_provider / preflight risk_provider 每次 tick / 每次 can_trade 現讀 risk-override.json,不快取、不需重啟。
- Preflight 4 gates 短路 — enabled → signing → margin → total exposure;先失敗者勝(第一個失敗 reason 即回)。
- Studio 是 viewer/intent layer 不是 executor — 只寫 risk-override.json 與 symbols.yml;所有送單檢查仍由 daemon preflight 執行。
M morning session(一般盤 08:45–13:45)
E evening session(夜盤 15:00–05:00 次日)
active 上線中
reference reference-only
new v2 新增
planned 規劃中未實作
MUST 不可違
SHOULD 預設可覆寫
MAY 建議
Trading Agent Architecture v3 · Hiram · 2026-04-21 · + 動態風控 slider + Preflight 4 gates + Studio Dashboard API + Phase 3 部分實裝