# MacroScope — 總經儀表板 · 學習 · 個股 · 復盤 · 日曆 一個給初學者用的美國總體經濟 + 投資學習工具箱。資料主要來自美國聖路易聯儲 **FRED**(免費、公開)、Yahoo Finance、SEC EDGAR 等官方與公開來源。全中文介面、每張卡片與檢查都有白話解釋,並用透明公式算出「總經健康分數」。 強調「照問題學、不要硬背名詞」:從總經水位、財報健檢、六層投資地圖、交易復盤等實際任務出發,隨時可跳轉回對應的投資原則與名詞。內建市場日曆(含自訂追蹤財報)與可帶頁面上下文的 AI 助手(支援 Grok 與 OpenCode Go)。 > **為什麼需要後端?** FRED 官方 API 不允許瀏覽器直接呼叫(沒有 CORS),且金鑰不能放在前端。本專案用一支很小的 Node 伺服器當代理:金鑰只留在伺服器,瀏覽器只跟自己的 `/api/*` 溝通。 --- ## 目錄 - [快速開始](#快速開始) - [主要功能](#主要功能) - [專案在整體 repo 中的位置](#專案在整體-repo-中的位置) - [資料夾結構](#資料夾結構) - [系統架構](#系統架構) - [API 端點](#api-端點) - [資料流與快取](#資料流與快取) - [建立知識庫](#建立知識庫) - [環境變數](#環境變數) - [技術棧](#技術棧) - [指標與資料來源](#指標與資料來源) - [常見問題](#常見問題) - [免責聲明](#免責聲明) --- ## 快速開始 ### 1. 申請 FRED 金鑰(約 1 分鐘) 到 註冊,取得 32 碼金鑰(免費、即時核發)。 ### 2. 設定金鑰 啟動後到頂部 **AI 設定** 頁填入: | 變數 | 用途 | |------|------| | `FRED_API_KEY` | 總經 + 部分日曆 | | `GROK_API_KEY` / `OPENCODE_GO_API_KEY` | AI 助手(可擇一或都填) | | `AI_ACTIVE_PROVIDER` | 預設 provider(`grok` 或 `opencode-go`) | 設定會寫入本機 `.env`,**不會出現在瀏覽器**。 或手動複製範例檔: ```bash cp .env.example .env # 編輯 .env 填入金鑰 ``` ### 3. 安裝並啟動 ```bash npm install npm run build:knowledge # 學習教材前置(需 emmy 知識庫,見下方) npm start # 開發模式(自動重啟):npm run dev ``` 瀏覽器開啟 `http://localhost:3000`。看到 `MacroScope 已啟動` 即成功。 > 還沒設 FRED 金鑰也能啟動,總經頁會顯示設定教學。 --- ## 主要功能 頂部分頁使用 **hash 路由**(無前端框架): | 路由 | 視圖 | 說明 | |------|------|------| | `#/` | 總經儀表板 | 31 項 FRED 指標、健康分數、殖利率曲線 | | `#/calendar` | 市場日曆 | FOMC/CPI/非農等 + 自訂追蹤財報 | | `#/learn` | 學習教材 | Obsidian 知識庫快照、wikilink、知識圖譜 | | `#/stock` | 個股工具 | 財報、走勢、健檢、投資地圖、回測 | | `#/journal` | 交易復盤 | 交易紀錄、損益、勝率、分組統計 | | `#/settings` | AI 設定 | 金鑰、provider、模型清單 | 右下角常駐 **AI 助手**,會依目前頁面自動帶入上下文。 ### 總經儀表板 - 31 項真實 FRED 指標,分 6 組(利率 & 殖利率、通膨、勞動、成長、貨幣 & 信用、市場情緒 & 大宗)。 - 每張卡片:最新值、變動%、sparkline、三段白話解釋、資料來源與更新頻率。 - **總經健康分數**(0–100)與景氣燈號,附完整 breakdown。 - 殖利率曲線 + 歷史事件標記(`EVENTS` / `EPISODES`)。 - 點卡片開走勢大圖 Modal,支援多區間與分數累積走勢。 ### 市場日曆 - 未來約 60 天重要事件(央行、通膨、就業、四巫日、休市等)。 - **追蹤財報**:自訂股票代號 watchlist,earnings 顯示在對應日期。 - 多源抓取(官方 iCal、FRED、BLS、BEA、Nasdaq),伺服器每日快取。 ### 學習教材 - 由 `emmy/emmy` Obsidian 知識庫建置快照(原則、案例、名詞、公司、單集、知識圖譜)。 - wikilink `[[目標]]` 站內跳轉、Markdown + Mermaid、個人筆記(localStorage)。 - 與總經、個股、復盤雙向連結。 ### 個股工具 - **指標面板**:報價、三表、比率、Company Intel。 - **價格走勢**:多區間/日週月線圖(Yahoo 主力,Nasdaq 備援)。 - **財報健檢**:五步驟紅黃綠燈 + 連結知識庫。 - **投資地圖**:六層漏斗互動流程。 - **回測**:買進持有 / 定期定額 / 均線 / 逢大跌等策略。 ### 交易復盤 - CRUD 交易紀錄,自動損益、勝率、Payoff、分組分析。 - 資料存於 SQLite `trades` 表。 ### AI 助手 - Provider:Grok、OpenCode Go;可從 `/api/ai/models` 抓取可用模型。 - `/api/ai/context` 組裝目前頁面精簡摘要 → `/api/ai/chat` 轉發 LLM。 - 繁體中文、先結論再依據,一律附學習免責聲明。 --- ## 專案在整體 repo 中的位置 本目錄是 `finance` monorepo 下的 **Web 應用**;學習內容來自同層的 Obsidian 知識庫: ``` finance/ # 父目錄(git repo 根目錄) ├── emmy/ │ └── emmy/ # Obsidian 投資知識庫(Markdown + wikilink) │ ├── 投資原則/ │ ├── 名詞/ │ └── ... └── web/ # ← 本專案(MacroScope) ├── server.js ├── index.html ├── app.js ├── lib/ ├── data/ # build:knowledge 產物 └── data.db # 執行期 SQLite(.gitignore) ``` 建置腳本預期路徑:`../../emmy/emmy`(相對 `web/scripts/`)。 --- ## 資料夾結構 ``` web/ ├── index.html # 總經視圖 HTML 骨架 + 內聯渲染(卡片、Modal、圖表) ├── app.js # SPA 路由、五視圖 init、AI widget、Markdown/wikilink ├── app.css # 全站樣式(淺色、玻璃擬態 header) ├── server.js # Express:靜態檔 + 全部 /api + 快取 + AI proxy + .env 管理 │ ├── lib/ # 領域邏輯(多數檔案開頭有職責說明) │ ├── indicators.js # 31 指標字典 + 6 分組 + 卡片 tip │ ├── fred.js # FRED 抓取、YoY/MoM、sparkline、殖利率曲線 │ ├── score.js # 健康分數、regime、breakdown、signals │ ├── context.js # 依歷史序列產生白話脈絡 │ ├── events.js # 歷史事件 EVENTS、危機案例 EPISODES │ ├── db.js # SQLite:cache / series / score_history / trades │ ├── marketdata.js # Yahoo chart + Nasdaq 備援 │ ├── fundamentals.js # Yahoo quoteSummary + SEC EDGAR 正規化三表 │ ├── fincheck.js # 財報基本功五步驟規則引擎 │ ├── backtest.js # 四種策略回測與績效統計 │ ├── investmap.js # 六層投資地圖設定與問題 │ ├── calendar.js # 日曆事件彙整(多源) │ ├── calendar-fred.js # FRED 相關日曆源 │ ├── calendar-market.js # 市場結構(四巫、休市等) │ ├── calendar-i18n.js # 事件中文化 │ ├── calendar-cache.js # 日曆每日快取 + watchlist │ ├── companyintel.js # 管理層、內部人、新聞等 │ ├── knowledge.js # 載入 knowledge.json / notes.json │ ├── graph.js # wikilink → vis-network 圖譜 │ ├── learn-html.js # 學習路徑首頁渲染 │ └── glossary.js # 名詞提示 │ ├── data/ # 建置產物(可 commit JSON,執行期讀取) │ ├── knowledge.json # 課綱索引 + linkMap + 輕量條目 │ └── notes.json # 全筆記全文(kind:id → body) │ ├── scripts/ │ └── build-knowledge.mjs # 從 emmy/emmy 快照 → data/*.json │ ├── package.json ├── .env.example ├── .gitignore # 忽略 node_modules、.env、data.db └── README.md ``` **執行期產生、不進版控:** | 檔案 | 說明 | |------|------| | `data.db` | SQLite:快取、序列、分數歷史、交易、通用 JSON cache | | `.env` | API 金鑰與設定(可由設定頁寫入) | | `node_modules/` | npm 依賴 | --- ## 系統架構 ### 分層概覽 ```mermaid flowchart TB subgraph Browser["瀏覽器(Vanilla JS SPA)"] HTML[index.html] APP[app.js + app.css] HASH["Hash 路由 #/macro … #/settings"] AIW[AI 浮動面板] end subgraph Server["Node.js + Express(server.js)"] API["/api/* 路由"] CACHE[記憶體 + SQLite 快取] ENV[.env 讀寫] end subgraph Lib["lib/ 領域模組"] FRED[fred + indicators + score] MKT[marketdata + fundamentals] CAL[calendar-*] LEARN[knowledge + graph] TRD[db trades + fincheck + backtest] end subgraph External["外部資料源"] FREDAPI[FRED API] YAHOO[Yahoo Finance] SEC[SEC EDGAR] LLM[Grok / OpenCode Go] OFFICIAL[央行 / BLS / BEA / Nasdaq iCal] end subgraph Data["本機資料"] JSON[data/knowledge.json + notes.json] SQLITE[(data.db)] end Browser -->|fetch /api| Server Server --> Lib Lib --> FREDAPI Lib --> YAHOO Lib --> SEC Lib --> OFFICIAL Server --> LLM Lib --> JSON Lib --> SQLITE EMMY[(emmy/emmy)] -.->|build:knowledge| JSON ``` ### 前端模組職責 | 檔案 | 職責 | |------|------| | `index.html` | 總經頁 DOM、卡片/Modal/圖表渲染、頂部 nav | | `app.js` | `VIEW_IDS` 路由、`initCalendar/Learn/Stock/Journal/Settings`、wikilink/Markdown、AI context | | `app.css` | 各視圖版面與元件樣式 | ### 後端模組職責 | 檔案 | 職責 | |------|------| | `server.js` | 路由表、TTL 常數、`buildPayload` / `refreshAndCache`、財報/股價快取邏輯、AI summarizer、`SETTINGS_FIELDS` | --- ## API 端點 所有 API 前綴為 `/api`,回傳 JSON(錯誤時附 `error` 訊息)。 ### 總經 | 方法 | 路徑 | 說明 | |------|------|------| | GET | `/api/macro` | 整包總經 payload;`?fresh=1` 強制重抓 | | GET | `/api/series/:key` | 單一指標歷史(走勢大圖) | | GET | `/api/score-history` | 每日健康分數累積 | | GET | `/api/events` | 歷史事件與危機案例 | ### 學習 | 方法 | 路徑 | 說明 | |------|------|------| | GET | `/api/knowledge` | 知識庫索引與 metadata | | GET | `/api/note/:kind/:id` | 單篇筆記全文 | | GET | `/api/graph` | vis-network 節點與邊 | ### 個股與日曆 | 方法 | 路徑 | 說明 | |------|------|------| | GET | `/api/fundamentals/:symbol` | 三表、比率、財測等 | | GET | `/api/price/:symbol` | 歷史 OHLC(`range`, `interval`) | | GET | `/api/quote/:symbol` | 即時報價 | | GET | `/api/profile/:symbol` | 公司簡介 | | GET | `/api/company-intel/:symbol` | 管理層、內部人、新聞 | | GET | `/api/backtest/:symbol` | 策略回測結果 | | GET | `/api/investmap` | 六層地圖設定 | | GET | `/api/calendar` | 日曆事件 payload | | GET/PUT | `/api/calendar/watchlist` | 追蹤財報代號清單 | ### 復盤 | 方法 | 路徑 | 說明 | |------|------|------| | GET | `/api/trades` | 交易列表 | | GET | `/api/trades/stats` | 統計摘要 | | POST | `/api/trades` | 新增 | | PUT | `/api/trades/:id` | 更新 | | DELETE | `/api/trades/:id` | 刪除 | ### AI 與設定 | 方法 | 路徑 | 說明 | |------|------|------| | POST | `/api/ai/models` | 依 provider 列出可用模型 | | POST | `/api/ai/context` | 組裝目前頁面上下文 | | POST | `/api/ai/chat` | 帶 context 的對話 | | GET | `/api/settings/env` | 讀取設定(金鑰遮罩) | | POST | `/api/settings/env` | 寫入 `.env` | | GET | `/api/health` | `{ ok, knowledge }` 健康檢查 | 靜態檔:根目錄 `index.html`、`app.js`、`app.css` 由 Express 直接提供。 --- ## 資料流與快取 | 功能 | 路徑 | 外部來源 | 持久化 | |------|------|----------|--------| | 總經 | `/api/macro` | FRED + Yahoo(黃金) | 記憶體 + `cache`/`series`/`score_history` | | 日曆 | `/api/calendar` | 多源 iCal / API | `cache` 表(24h) | | 學習 | `/api/knowledge` | `data/*.json` | 建置時快照 | | 財報 | `/api/fundamentals/:s` | Yahoo → SEC | 通用 cache + SEC 探針 | | 股價 | `/api/price/:s` | Yahoo → Nasdaq | 日線 6h / 週月 1d TTL | | 復盤 | `/api/trades` | — | `trades` 表 | | AI | `/api/ai/chat` | Grok / OpenCode | 無持久(僅請求日誌於 console) | **SQLite 表(`lib/db.js`):** - `cache` — macro 整包、fundamentals、hist、quote、calendar 等 JSON - `series` — 各 FRED 指標完整歷史點 - `score_history` — 每日健康分數 - `trades` — 使用者交易復盤 **財報快取邏輯(`server.js`):** 1. 軟 TTL(預設 12h)內:完全不連網,直接用 DB。 2. 超過軟 TTL:輕量 SEC `getLatestFilingInfo` 探針;無新申報則續用快取。 3. 硬上限(預設 3 天)或探針失敗且過期:重抓 Yahoo/EDGAR。 失敗時盡量回傳 stale 資料並標記 `degraded`,避免畫面卡住。 --- ## 建立知識庫 學習教材、財報健檢連結、投資地圖原則、知識圖譜皆依賴 `emmy/emmy` 快照: ```bash npm run build:knowledge ``` 產出: - `data/knowledge.json` — 索引、分類、linkMap - `data/notes.json` — 全文(key = `kind:id`) `emmy/` 更新後重跑即可。未建置時學習頁會提示,且 `/api/health` 的 `knowledge: false`。 --- ## 環境變數 見 `.env.example`: | 變數 | 預設 | 說明 | |------|------|------| | `FRED_API_KEY` | — | 必填(總經) | | `PORT` | `3000` | 伺服器埠 | | `CACHE_TTL_SECONDS` | `3600` | 總經整包快取 | | `FUND_SOFT_HOURS` | `12` | 財報軟 TTL | | `FUND_HARD_DAYS` | `3` | 財報硬上限 | | `HIST_SOFT_HOURS` | `6` | 日線股價快取 | | `QUOTE_TTL_SECONDS` | `60` | 報價快取 | | `GROK_*` / `OPENCODE_GO_*` | — | AI provider | | `AI_ACTIVE_PROVIDER` | `grok` | 預設 provider | --- ## 技術棧 | 層級 | 技術 | |------|------| | 執行環境 | Node.js ≥ 18(ESM) | | 後端 | Express 4、`dotenv`、內建 `node:sqlite` | | 前端 | 純 HTML/CSS/Vanilla JS,無 bundler | | CDN | mermaid@11、vis-network@9 | | 依賴數 | 僅 2 個 npm 套件(express、dotenv) | 外部 API 金鑰與抓取**全部經 server 代理**,不出現在瀏覽器。 --- ## 指標與資料來源 絕大多數指標對應 FRED 序列;黃金改用 Yahoo 期貨(FRED 無良好日線)。 ### 免費替代指標(卡片標「替代」) | 理想指標 | 替代序列 | 說明 | |----------|----------|------| | ISM 製造業 PMI | `GACDFSA066MSFRBPHI` | 費城聯儲製造業景氣 | | 世界大型企業聯合會 CCI | `UMCSENT` | 密西根消費者信心 | | 領先指標 LEI | `RECPROUSM156N` | NY Fed 衰退機率模型 | 另含工業生產年增(`INDPRO`)作實體經濟補充。 ### 總經健康分數 從 **50 分(中性)** 出發,依殖利率曲線、衰退機率、通膨、就業、信用利差等規則加減,限制 0–100。中性參考指標(美元、油價等)不計分。 | 分數 | 燈號 | |------|------| | ≥ 65 | 景氣穩健 | | 50–64 | 溫和成長 | | 35–49 | 景氣放緩 | | < 35 | 衰退風險高 | 教學用簡化模型,**不構成投資建議**。 --- ## 常見問題 - **總經顯示要設定金鑰?** → AI 設定頁填 `FRED_API_KEY` 或編輯 `.env` 後重整。 - **學習頁空白?** → 確認 `finance/emmy/emmy` 存在,執行 `npm run build:knowledge`。 - **個股或卡片抓取失敗?** → 按「↻ 更新」;多數有 stale 回退。 - **AI 沒帶頁面資料?** → 設定 provider + model,在對應視圖(個股/學習筆記)再開 AI 面板。 - **要改指標或分數規則?** → 編輯 `lib/indicators.js`、`lib/score.js`,重啟 server。 --- ## 免責聲明 本專案所有內容、工具、AI 回覆、回測與統計**僅供個人學習與研究**,不構成投資、財務、稅務或任何專業建議。投資有風險,請以 FRED、SEC、Yahoo 等官方來源為準。過去績效不代表未來表現。