Skip to content

Commit 65ccdee

Browse files
authored
Merge pull request #15 from cablate/feat/web-config
feat: Web 設定面板 + 測試按鈕 + AGPL-3.0
2 parents 5693b99 + cc2d310 commit 65ccdee

12 files changed

Lines changed: 1645 additions & 216 deletions

File tree

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ RUN npm run build
2020
ENV NODE_ENV=production
2121
ENV DATA_DIR=/data
2222

23-
CMD ["node", "dist/index.js", "--cron"]
23+
EXPOSE 3000
24+
25+
CMD ["node", "dist/cli.js", "serve"]

LICENSE

Lines changed: 661 additions & 21 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 78 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
# banini-tracker
66

7-
追蹤「股海冥燈」巴逆逆(8zz)的 Facebook 社群貼文,透過 Apify 抓取、AI 反指標分析、多平台即時推送(Telegram / Discord / LINE),並自動追蹤預測準確度。
7+
> **AGPL-3.0** — 使用、修改或部署本專案,必須標明原作者 **[cablate](https://github.com/cablate)**、附上[本 repo 連結](https://github.com/cablate/banini-tracker),並以相同授權公開原始碼。網路服務部署亦同。
8+
>
9+
> 本專案於 2026/04/13 從 MIT 切換至 AGPL-3.0。此日期之前取得的版本仍適用 MIT 授權。
10+
11+
追蹤「股海冥燈」巴逆逆(8zz)的 Facebook 社群貼文,透過 AI 反指標分析、多平台即時推送(Telegram / Discord / LINE),並自動追蹤預測準確度。
812

913
- 辨識她提到的標的(個股、ETF、原物料)
10-
- 判斷她的操作(買入 / 被套 / 停損)
1114
- 反轉推導(她停損 → 可能反彈、她買入 → 可能下跌)
1215
- 推導連鎖效應(油價跌 → 製造業利多 → 電子股受惠)
1316
- 自動記錄預測,追蹤 5 個交易日的實際走勢
@@ -31,78 +34,76 @@
3134

3235
---
3336

34-
> **Claude Code 使用者?** 直接把 [`skill/SKILL.md`](skill/SKILL.md) 加到你的 `.claude/skills/` 就能用。Claude 自己當分析引擎,不需要額外 LLM。
37+
## 快速開始
3538

36-
支援兩種使用模式:
37-
- **常駐排程**:Docker 部署,自動盤中/盤後排程 + LLM 分析 + 多平台推送(Telegram / Discord / LINE) + 預測追蹤
38-
- **CLI 工具**`npx @cablate/banini-tracker`,搭配 Claude Code 等 AI 手動執行分析
39+
四種使用方式,按推薦順序:
3940

40-
## 快速開始(常駐排程
41+
### 1. Zeabur 一鍵部署(推薦
4142

42-
```bash
43-
# 1. 複製設定
44-
cp .env.example .env
45-
# 填入必要項目,並設定至少一個通知管道(Telegram / Discord / LINE)
43+
[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/banini-tracker)
4644

47-
# 2. Docker 部署
45+
部署後打開分配的網域,首次進入設定管理員帳密,然後在 Web UI 填入 API key 和通知管道。不需要手動設定環境變數。
46+
47+
### 2. Docker
48+
49+
```bash
4850
docker build -t banini-tracker .
49-
docker run -d --name banini --env-file .env -v banini-data:/data banini-tracker
51+
docker run -d --name banini --env-file .env -v banini-data:/data -p 3000:3000 banini-tracker
52+
```
53+
54+
部署後打開 `http://localhost:3000` 進入設定頁面。也可以直接用 `.env` 檔設定環境變數(見下方)。
55+
56+
### 3. npx 直接啟動
5057

51-
# 3. 或本地直接跑
58+
```bash
59+
npx @cablate/banini-tracker serve
60+
npx @cablate/banini-tracker serve --port 8080
61+
```
62+
63+
不需 Docker,直接在本機啟動常駐服務(排程 + Web 設定頁面)。打開 `http://localhost:3000` 進入設定。適合有 Node.js 環境的使用者。
64+
65+
### 4. 本地開發
66+
67+
```bash
68+
cp .env.example .env # 填入必要設定
5269
npm install && npm run start
5370
```
5471

55-
### 排程規則
72+
## 排程規則
5673

5774
| 排程 | 時間 | 說明 |
5875
|------|------|------|
59-
| 早晨補漏 | 每天 08:00 | 抓前一晚 22:00 後的貼文(3 篇) |
60-
| 盤中 | 週一~五 09:07-13:07 每 30 分 | 抓 08:30 後的貼文(1 篇) |
61-
| 追蹤更新 | 週一~五 15:00 | 更新預測追蹤(收盤後抓 OHLC) |
62-
| 盤後 | 每天 23:03 | 抓 13:30 後的貼文(3 篇) |
76+
| 早晨補漏 | 每天 08:00 | 抓前一晚的貼文(3 篇) |
77+
| 盤中 | 週一~五 09:07-13:07 每 30 分 | 即時追蹤(1 篇) |
78+
| 追蹤更新 | 週一~五 15:00 | 收盤後更新預測追蹤 |
79+
| 盤後 | 每天 23:03 | 當日彙整(3 篇) |
6380

64-
每個排程只抓自己時間窗口內的貼文,搭配 seen.json 去重,確保無死角且不重複。
81+
## 設定
6582

66-
### npm scripts
83+
### Web UI(Zeabur / Docker)
6784

68-
| 指令 | 說明 |
69-
|------|------|
70-
| `npm run start` | 常駐排程模式(全部排程自動跑) |
71-
| `npm run dev` | 單次執行(FB 3 篇) |
72-
| `npm run dry` | 只抓取,不呼叫 LLM |
73-
| `npm run market` | 盤中模式(FB 1 篇) |
74-
| `npm run evening` | 盤後模式(FB 3 篇) |
85+
常駐模式會在 port 3000 啟動設定頁面。首次進入建立管理員帳密,之後登入即可修改設定。修改後下次排程執行自動生效,不需重啟。
7586

76-
### .env 設定
87+
### 環境變數(.env
7788

78-
```
79-
APIFY_TOKEN=apify_api_...
80-
LLM_BASE_URL=https://api.deepinfra.com/v1/openai
81-
LLM_API_KEY=...
82-
LLM_MODEL=MiniMaxAI/MiniMax-M2.5
83-
TG_BOT_TOKEN=...
84-
TG_CHANNEL_ID=-100...
85-
86-
# Discord Bot(選填,與 Telegram 擇一或同時使用)
87-
DISCORD_BOT_TOKEN=...
88-
DISCORD_CHANNEL_ID=...
89-
90-
# LINE(選填,與其他通知管道同時使用)
91-
LINE_CHANNEL_ACCESS_TOKEN=...
92-
LINE_TO=target_user_or_group_id
93-
94-
# 影片轉錄(選填,啟用後自動轉錄影片貼文)
95-
TRANSCRIBER=groq
96-
GROQ_API_KEY=gsk_...
97-
98-
# FinMind API(選填,免費可用,註冊可提高額度)
99-
FINMIND_TOKEN=...
100-
101-
# 資料目錄(Docker 建議掛載 /data)
102-
DATA_DIR=/data
103-
```
89+
如果不使用 Web UI,也可以直接設定環境變數:
90+
91+
| 變數 | 必填 | 說明 |
92+
|------|------|------|
93+
| `APIFY_TOKEN` || Apify API token |
94+
| `LLM_API_KEY` || LLM API key |
95+
| `LLM_BASE_URL` || 預設 DeepInfra |
96+
| `LLM_MODEL` || 預設 MiniMax-M2.5 |
97+
| `TG_BOT_TOKEN` + `TG_CHANNEL_ID` | 至少一組 | Telegram 通知 |
98+
| `DISCORD_BOT_TOKEN` + `DISCORD_CHANNEL_ID` | 至少一組 | Discord 通知 |
99+
| `LINE_CHANNEL_ACCESS_TOKEN` + `LINE_TO` | 至少一組 | LINE 通知(Free plan 200 則/月) |
100+
| `TRANSCRIBER` || `noop`(預設)或 `groq` |
101+
| `GROQ_API_KEY` || Groq Whisper 影片轉錄用 |
102+
| `FINMIND_TOKEN` || 股價查詢(免費可用) |
104103

105-
## 預測追蹤系統
104+
Web UI 和環境變數可以混用,Web UI 的設定優先。
105+
106+
## 預測追蹤
106107

107108
LLM 分析出標的後,系統自動:
108109

@@ -111,113 +112,47 @@ LLM 分析出標的後,系統自動:
111112
3. **追蹤 5 個交易日**:每天 15:00 收盤後抓 OHLC,記錄漲跌幅
112113
4. **同股票取代**:新預測自動取代同標的舊預測(supersede 機制)
113114

114-
勝敗判定在查詢時決定,支援多維度分析(不同持有天數、信心度分群、操作類型)。
115-
116-
### 資料儲存
117-
118-
使用 SQLite(better-sqlite3),資料表:
119-
120-
|| 用途 |
121-
|----|------|
122-
| `posts` | 所有貼文原文(即時 + 歷史回測統一來源) |
123-
| `predictions` | 預測記錄(標的、方向、基準價、狀態) |
124-
| `price_snapshots` | 每日 OHLC 快照(5 天追蹤期) |
125-
126-
資料庫位置:`$DATA_DIR/banini.db`(Docker 掛載 `/data`,本地 `~/.banini-tracker/`
127-
128115
### 公開資料集
129116

130-
[`data/banini-public.db`](data/banini-public.db) 提供去識別化的預測資料,包含 345 筆預測記錄與對應的價格快照,不含原始貼文內容。可直接用於分析或驗證反指標勝率
117+
[`data/banini-public.db`](data/banini-public.db) 提供去識別化的預測資料345 筆預測 + 價格快照),不含原始貼文
131118

132119
```bash
133-
# 快速查看
134120
sqlite3 data/banini-public.db "SELECT symbol_name, reverse_view, base_price, status FROM predictions LIMIT 10"
135121
```
136122

137-
## CLI 工具模式
123+
## CLI 工具
138124

139-
不需 clone repo,任何環境直接用
125+
不需 clone repo,搭配 Claude Code 等 AI 使用
140126

141127
```bash
142-
# 初始化設定
143-
npx @cablate/banini-tracker init \
144-
--apify-token YOUR_APIFY_TOKEN \
145-
--tg-bot-token YOUR_TG_BOT_TOKEN \
146-
--tg-channel-id YOUR_TG_CHANNEL_ID
128+
# 啟動常駐服務(排程 + Web UI)
129+
npx @cablate/banini-tracker serve
147130

148-
# 抓取 Facebook 最新 3 篇
149-
npx @cablate/banini-tracker fetch -s fb -n 3 --mark-seen
131+
# 初始化 CLI 設定
132+
npx @cablate/banini-tracker init --apify-token YOUR_TOKEN
150133

151-
# 抓取指定日期區間(回測用)
152-
npx @cablate/banini-tracker fetch --since 2025-04-01 --until 2025-05-01 -n 100
134+
# 抓取貼文
135+
npx @cablate/banini-tracker fetch -n 3 --mark-seen
153136

154-
# 推送結果到 Telegram
137+
# 推送到 Telegram
155138
npx @cablate/banini-tracker push -f report.txt
156139
```
157140

158-
### CLI 指令
159-
160-
| 指令 | 說明 |
161-
|------|------|
162-
| `init` | 初始化設定檔(`~/.banini-tracker.json`|
163-
| `config` | 顯示目前設定 |
164-
| `fetch` | 抓取貼文,輸出 JSON 到 stdout |
165-
| `push` | 推送訊息到 Telegram |
166-
| `seen list` | 列出已讀貼文 ID |
167-
| `seen mark <id...>` | 標記貼文為已讀 |
168-
| `seen clear` | 清空已讀紀錄 |
169-
170-
### fetch 選項
171-
172-
```
173-
-s, --source <source> 來源:fb(預設 fb)
174-
-n, --limit <n> 每個來源抓幾篇(預設 3)
175-
--since <date> 只抓此時間之後的貼文(YYYY-MM-DD / ISO 時間戳 / 相對時間如 "2 months")
176-
--until <date> 只抓此時間之前的貼文
177-
--no-dedup 不去重
178-
--mark-seen 輸出後自動標記已讀
179-
```
180-
181-
### push 選項
182-
183-
```
184-
-m, --message <text> 直接帶訊息
185-
-f, --file <path> 從檔案讀取(推薦多行內容用這個)
186-
--parse-mode <mode> HTML / Markdown / none(預設 HTML)
187-
```
188-
189-
不帶 `-m``-f` 時從 stdin 讀取。
190-
191-
### 搭配 Claude Code 使用
192-
193-
在 Claude Code 的 skill 中,Claude 自己就是分析引擎:
194-
195-
1. `fetch` 抓貼文 → Claude 讀 JSON
196-
2. Claude 分析 + WebSearch 查最新走勢
197-
3. Claude 組報告 → `push -f` 推送 Telegram
141+
> **Claude Code 使用者?** 直接把 [`skill/SKILL.md`](skill/SKILL.md) 加到你的 `.claude/skills/` 就能用。Claude 自己當分析引擎,不需要額外 LLM。
198142
199-
詳見 [`skill/SKILL.md`](skill/SKILL.md)
143+
完整指令說明見 `npx @cablate/banini-tracker --help`
200144

201145
## 費用估算
202146

203-
| 項目 | 單次費用 | 頻率 | 月估算 |
204-
|------|---------|------|--------|
205-
| Facebook 抓取(Apify) | ~$0.005/篇 | ~270 篇/月 | ~$1.35 |
206-
| LLM 分析(常駐模式) | 依模型而定 | 同上 | 依模型定價 |
207-
| 影片轉錄(Groq Whisper) | ~$0.006/分鐘 | 視影片數量 | 極低 |
208-
| 股價查詢(FinMind) | 免費 | 每日收盤後 | $0 |
209-
| 通知推送(TG / DC) | 免費 || $0 |
210-
| LINE 推送 | Free plan 200 則/月 | 同上 | $0(一般用量) |
211-
212-
> CLI 模式搭配 Claude Code 使用不需 LLM 費用,Claude 自己分析。
213-
> 回測歷史資料加日期篩選:~$7/千篇($5 基本 + $2 date filter add-on)。
214-
215-
## 為什麼只用 Facebook?
216-
217-
早期版本同時支援 Threads 和 Facebook 爬取,後來基於兩個原因移除了 Threads:
147+
| 項目 | 月估算 |
148+
|------|--------|
149+
| Facebook 抓取(Apify) | ~$1.35(~270 篇) |
150+
| LLM 分析 | 依模型定價 |
151+
| 通知推送(TG / DC) | 免費 |
152+
| LINE 推送 | Free plan 200 則/月 |
153+
| 股價查詢(FinMind) | 免費 |
218154

219-
1. **費用差距大**:Threads 每次抓取 ~$0.15(Pay-per-event),Facebook 只要 ~$0.02(CU 計費),差 7 倍以上
220-
2. **FB 參考價值更高**:巴逆逆的投資相關貼文(持倉截圖、操作心得)主要發在 Facebook 粉專,Threads 多為生活日常,反指標參考價值較低
155+
> CLI 模式搭配 Claude Code 不需 LLM 費用,Claude 自己分析。
221156
222157
## Star History
223158

@@ -235,4 +170,4 @@ npx @cablate/banini-tracker push -f report.txt
235170

236171
## License
237172

238-
MIT
173+
[AGPL-3.0](LICENSE)

package-lock.json

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
"claude"
2727
],
2828
"author": "cablate",
29-
"license": "MIT",
29+
"license": "AGPL-3.0-only",
3030
"dependencies": {
31+
"@hono/node-server": "^1.19.13",
3132
"better-sqlite3": "^12.8.0",
3233
"commander": "^13.0.0",
3334
"dotenv": "^16.4.0",
3435
"groq-sdk": "^1.1.2",
36+
"hono": "^4.12.12",
3537
"node-cron": "^4.2.1",
3638
"openai": "^4.0.0"
3739
},

0 commit comments

Comments
 (0)